본문 바로가기

CS

컴퓨터 네트워킹 하향식 접근[Chapter 3]

[3.1] 트랜스포트 계층 서비스 및 개요

  • 트랜스포트 계층 프로토콜은 애플리케이션 프로세스 간의 논리적 통신을 제공한다
    • 논리적 통신이란 애플리케이션의 관점에서 보면 프로세스들이 동작하는 호스트들이 직접 연결된 것처럼 보인다는 것을 의미
    • 애플리케이션 프로세스는 메시지 움반을 위해 트랜스포트 계층에서 제공하는 논리적 통신을 사용한다
  • 트랜스포트 계층 프로토콜은 네트워크 라우터가 아닌 종단시스템에서 구현된다
    • 송신측의 트랜스포트 계층은 애플리케이션 프로세스에서 수신한 메시지를 세그먼트로 변환한다
    • 애플리케이션 메시지를 세그먼트로 만들기 위해 작은 조각으로 분할하고 각각의 조각에 트랜스포트 계층 헤더를 추가한다
    • 이후 송신 종단 시스템에 있는 네트워크 계층으로 세그먼트를 전달하고 여기서 세그먼트가 네트워크 계층 패킷 안에 캡슐화되어 목적지로 전달된다
    • 수신 측에서 네트워크 계층은 전달받은 패킷으로 부터 세그먼트를 추출하고 트랜스포트 계층으로 세그먼트를 보낸다
    • 이후 트랜스 포트 계층은 세그먼트의 데이터를 애플리케이션 계층에서 사용할 수 있도록 처리한다.

3.1.1 - 트랜스포트 계층과 네트워크 계층 사이의 관계

  • 트랜스포트 계층 프로토콜은 각기 다른 호스트에서 동작하는 프로세스들 사이의 논리적 통신을 제공하지만 네트워크 계층 프로토콜은 호스트들 사이의 논리적 통신을 제공한다
  • 편지 예시
    • A가정과 B가정의 구성원들은 각각의 가정으로 편지를 주고받는다
    • A가정에서는 아빠가, B가정에서는 엄마가 편지를 모아서 집배원에게 전달한다
    • 또 집배원에게 받은 편지를 분배하는 일 또한 A가정에서 아빠, B가정에서 엄마가 담당한다
    • 위 가정에서 각각의 호스트 = 집, 프로세스 = 가족 구성원, 에플리케이션 메시지 = 편지 내용, 트랜스 포트 계층 프로토콜 = A의 아빠, B의 엄마, 네트워크 계층 프로토콜 = 집배원
    • A의 아빠, B의 엄마가 편지를 모아서 집배원에게 전달하는 것 -> 다중화(multiplexing)
    • A의 아빠, B의 엄마가 집배원에게 편지를 받아 분배하는 것 -> 역다중화(demultiplexing)

3.1.2 - 인터넷 트랜스포트 계층의 개요

  • UDP(User Datagram Protocol) - 비신뢰적, 비연결형 서비스
    • 데이터가 손상되지 않고 목적지 프로세스에 도착한다는 것을 보장하지 않는다
    • 트래픽 조절 x
  • TCP(Transmission Control Protocol) - 신뢰적, 연결지향형 서비스
    • 흐름 제어, 순서번호, 확인응답, 타이머를 사용함으로서 데이터가 순서대로 정확하게 전달되도록 확실하게 한다
    • 혼잡제어란 트래픽 제어해서 네트워크 혼잡을 방지하는 것
  • UDP와 TCP 모두 헤더에 오류 검출 필드를 포함해 무결성 검사를 제공
  • 네트워크 계층 프로토콜은 인터넷 프로토콜(Internet Protocol, IP)
    • IP는 호스트들간 세그먼트를 전달하기 위해 최선을 다하지만 보장하지는 않음(순서나 무결성등을 보장하지 않음)
    • 위와같은 이유로 IP는 비신뢰적인 서비스

3.1.3 - 다중화와 역다중화

  • 다중화(multiplexing)
    • 송신측에서 세그먼트를 생성하기 위해 각 데이터에 헤더 정보로 캡슐화 하고 그 세그먼트들을 네트워크 계층으로 전달하는 작업
    • 요구사항
      • 소켓은 유일한 식별자를 갖는다 - 출발지 포트 번호 필드
      • 각 세그먼트는 세그먼트가 전달될 적절한 소켓을 가리키는 특별한 필드를 갖는다 - 목적지 포트 번호 필드
  • 역다중화(demultiplexing)
    • 수신 측에서 세그먼트 필드 검사하고 이 세그먼트의 데이터를 올바른 소켓으로 보내는 작업
    • 순서(이자 UDP의 가장 기본적인 동작 방식)
      • 호스트의 각 소켓은 포트 번호를 할당 받는다
      • 세그먼트가 호스트에 도착하면, 트랜스포트 계층은 세그먼트 안의 목적지 포트 번호를 검사하고 상응하는 소켓으로 세그먼트를 보낸다
      • 세그먼트의 데이터는 소켓을 통해 해당되는 프로세스로 전달된다
  • 포트번호
    • 0~65535까지의 16비트 정수
    • 0~1023까지의 포트 번호를 '잘 알려진 포트 번호'라고 하며 사용을 엄격하게 제한
      • ex) HTTP(80), FTP(21)
      • RFC 1700에 명시되어있음

비연결형 다중화와 역다중화

  • 트랜스포트 계층은 현재 호스트에서 UDP포트로 사용하지 않는 1024~65535 사이의 포트 번호를 소켓에게 할당한다.
  • 예를 들어 UDP 소켓 1900 의 호스트 A -> UDP소켓 4600 호스트 B로의 데이터 전송을 가정
    • 송신측 
      • 호스트 A의 트랜스포트 계층은 애플리케이션 데이터, 출발지 포트번호(1900), 목적지 포트 번호(4600), 그리고 2개의 다른 값(추후 설명)을 포함하는 세그먼트 생성
      • 트랜스포트 계층은 해당 세그먼트를 네트워크 계층으로 전달하고 네트워크 계층은 해당 세그먼트를 IP 데이터그램으로 캡슐화해 수신 호스트로 전달
    • 수신측
      • 수신 호스트 B는 세그먼트 안의 목적지 포트번호(4600)을 검사하고 해당 소켓으로 전달
  • 만약 2개의 UDP세그먼트가 출발지 IP와 포트 번호가 모드 다르거나 둘 중 하나가 달라도 같은 목적지 IP와 포트번호를 가지면 같은 소켓을 통해 같은 프로세스로 잘 전달됨
    • 출발지 포트번호는 혹시라도 수신측이 회신을 해야할 때 사용될 뿐이다

연결지향형 다중화와 역다중화

  • 4개 요소(출발지 IP주소, 출발지 포트번호, 목적지 IP주소, 목적지 포트번호)의 집합에 의해 식별됨
    • 하나라도 다르면 정상적으로 도착 안함
  • 대략적인 순서
    • TCP 서버 애플리케이션은 '환영 소켓'을 갖고 있다.
    • TCP클라이언트는 소켓을 생성하고 '환영 소켓'으로 연결 설정 요청 세그먼트를 보낸다
    • 위에서 말한 4개요소를 토대로 새로운 소켓을 만들어 이 소켓으로 데이터를 주고 받는다

[3.3] 비연결형 트랜스포트 : UDP

  • UDP는 트랜스포트 계층 프로토콜이 할 수 있는 최소 기능으로 동작함
  • 다중화/역다중화, 간단한 오류검사를 제외한 아무것도 추가 x
  • TCP와 다르게 연결작업을 하지 않음
  • DNS는 UDP를 사용
  • 아래와 같은 이유로 많은 애플리케이션은 UDP에 더 적합함
    • 애플리케이션 레벨에서 더 정교한 제어
      • TCP는 혼잡제어로 지연등이 발생하는데 얘는 그냥 보내고 끝!
    • 연결 설정이 없음
    • 연결 상태가 없음
    • 오버 헤드가 8바이트 밖에 안됨(연결이나 네트워크 상황등을 위한 헤더 설정이 필요 없어서)
  • 근데 혼잡제어 안하면 네트워크가 폭주상태가 되기때문에 꼭 필요함(그래서 TCP 많이 쓰는 듯)
  • QUIC프로토콜은 UDP상에서 연결 지향형 이라고 하는데 추후에 정리 예정

3.3.1 - UDP 세그먼트 구조

  • UDP세그먼트는 2바이트씩 구성된 단 4개의 필드만을 갖는다
    • 출발지 포트번호, 목적지 포트번호, 길이, 체크섬

3.3.2 - UDP 체크섬

  • 체크섬은 오류 검출을 위한 것
    • 즉, 세그먼트가 목적지에 도착했을 때 비트에 대한 변경사항이 있는지 검사하는 것
  • 많은 링크 계층 프로토콜이 오류 검사를 제공하지만 모든 링크계층이 오류 검사를 보장하지 않기에 체크섬이 필요 - 종단과 종단의 원칙의 한 예
  • 오류 검출은 하지만 재전송같은 오류 회복을 위한 노력은 안함, 그냥 버리거나 손상된걸 애플리케이션 계층에게 넘겨주기도 함

[3.4] 신뢰적인 데이터 전송의 원리

  • 신뢰적인 데이터 전송 프로토콜(reliable data transfer protocol - RDT)
    • 전송된 데이터가 손상되거나 손실되지 않는다
    • 모든 데이터는 전송된 순서 그대로 전달된다

3.4.1 - 신뢰적인 데이터 전송 프로토콜의 구축

완벽하게 신뢰적인 채널상에서의 신뢰적인 데이터 전송 : rdt1.0 (네트워크에서 error, loss가 없다고 가정)

  • 보내는대로 도착하기에 딱히 할건 없음(피드백이나 오류 검출등)
  • 데이터 단위와 패킷의 차이점이 없음

비트 오류가 있는 채널상에서의 신뢰적 데이터 전송 : rdt2.0 (loss는 없지만 error는 있음)

  • Error탐지해서 잘 전송됬으면 ACK, 문제있으면 NAK라고 알려주기
    • checksum을 통해 오류를 검출함 
    • NAK이면 해당 패킷 반복해서 보내주셈 하는거
  • 전송 후 피드백을 기다리기에 전송 후 대기 프로토콜이라고함
  • 문제점
    • ACK이나 NAK의 응답이 손실된다면?(피드백이 손실된다면?)
      • 무조건 재전송한다?
        • 이러면 중복 패킷이 발생함
    • 그래서 나온게 sequenceNumber추가해서 수신된 패킷의 Number를 알려줌 -> 2.1
    • 근데 ACK(num) 도달하면 수신한거로 가정하고 안오면 수신안된거로 판단하기로 해서 NAKeh 없앰 -> 2.2
    • sequenceNumber는 0, 1의 1비트임
      • 전송하고 기다렸다가 응답 오면 보내는 방식이라서 0,1,0,1 번갈아가면서 할당하면 되기 때문

비트 오류와 손실 있는 채털상에서의 신뢰적인 데이터 전송 : rdt3.0(loss, error 둘 다 고려)

  • 타이머 만들어서 해당 타이머 다 될 때 까지 응답 없으면 유실로 판단하고 재전송

3.4.2 - 파이프라이닝된 신뢰적인 데이터 전송 프로토콜

  • 하나하나 전송하고 기다리고 하는건 말만 들어도 느림 -> 확인응답 기다리지 말고 그냥 일단 보내자!!(파이프라이닝(pipelining))
  • 파이프라이닝은...
    • sequenceNumber의 범위가 켜져야 한다
    • 송/수신측은 패킷들을 버퍼링 해야한다
      • 송신자는도착 응답이 오기 전 까지는 재전송을 위해 가지고 있어야 함
      • 수신사는 순서 맞추기 위해 상위 계층으로 올려보내지 말고 기다려야 함
    • GBN, SR방식등이 있음

3.4.3 - GBN(Go-Back-N)

https://www.youtube.com/watch?v=gaocB7unrqs  < 영상 보면 바로 이해됨

  • 1) 윈도 크기만큼의 패킷을 보낸다(ex 4라고 가정하고 (0, 1, 2, 3)을 보냈다)
  • 2) 0, 1, 2는 잘 도착 했다고 응답값이 왔는데 3에 대한 응답값이 없다?
  • 3) 그럼 송신자는 3부터 다시 4개를 보냄(3, 4, 5, 6)
  • 즉, 응답값이 안온 N부터 다시 보낸다!
  • 문제점
    • 근데 지금은 0, 1, 2에 대한 응답값이 온거지만
    • 1, 2, 3에 대한 응답값이 오고 0에 대한 응답값이 잘 온거라면??
    • 안타깝게도 0, 4, 5, 6을 보내는게 아니라 1, 2, 3 버리고 0, 1, 2, 3을 다시 보냄

3.4.4 - SR

https://www.youtube.com/watch?v=6fz_Wo8jkAc < 영상 보면 바로 이해됨

  • 이건 일단 지금까지 잘 받은 패킷의 다음 번호를 달라고 응답값을 보냄
  • 순서
    • 1)사이즈 정해서 보냄(4개라고 가정하고 (0, 1, 2, 3)을 보냄)
    • 2) 수신자는 0, 2, 3은 받았는데 1을 못받았음 -> 순서가 이상하니까 상위계층으로 안올리고 일단 버퍼에 갖고 있음
    • 3) 그러면 0받았을 때도 1달라고 응답하고 2받았을 때도 1달라고 응답하고 3받았을 때도 1 달라고 응답함 
    • 4) 나중에 다룰거지만 송신자는 타이머, 중복 응답 등을 통해 수신자가 필요한 패킷 다시 전송
    • 5) 수신자가 나중에 정상적으로 1을 받았다면 0123 순서 맞았으니까 상위 계층으로 올리고 이제 4달라고 응답함

[3.5] 연결지향형 트랜스포트 : TCP

3.5.1 - TCP 연결

  • TCP는 데이터 주고받기 전에 핸드셰이크 먼저하는 연결 지향형
  • TCP프로토콜은 오직 종단 시스템에서만 동작하고 중간의 요소에서는 동작 x
  • TCP는 전이중 서비스(full-duplex service)
    • sender가 receiver가 되고 receiver가 sender가 되기도 함
  • 단일 송신자, 단일 수신자 (point - to - point)
  • 세 방향 핸드 셰이크의 순서
    • 클라이언트가 특별한 TCP 세그먼트를 보낸다
    • 서버는 두 번째 특별한 TCP세그먼트로 응답한다
    • 클라이언트가 세 번째 특별한 세그먼트로 다시 응답하며 여기에서는 데이터가 포함될 수 있다
  • 송신측의 센더 -> 수신측의 리시버, 수신측의 센터 -> 송신측의 리시버 이렇게 통신함
  • 세그먼트로 모아 담을 수 있는 최대 데이터 양은 최대 세그먼트 크기(MSS)로 제한되고 MSS는 일반적으로 가장 큰 링크 계층 프레임의 길이(MTU)에 의해 결정된다
    • MTU는 1,500바이트

3.5.2 - TCP 세그먼트 구조

  • 헤더 필드와 데이터 필드로 구성되어 있으며 데이터 필드는 애플리케이션 계층의 메시지로 구성됨
  • 헤더 필드
    • UDP와 마찬가지로 송/수신지 정보, 체크섬은 당근 포함됨
    • 32비트 순서 번호 필드와 32비트 확인 응답 번호 필드
    • 16비트 수신 윈도 -> 흐름제어에 사용
    • 4비트 헤더 길이 필드: TCP헤더의 길이를 나타냄
    • 옵션 필드 : 송/수신자의 최대 세그먼트 크기(MSS)를 협상하거나 고속 네트워크에서 사용하기 위한 윈도 확장 요소로 이용됨
    • 플래그 필드: 확인 응답을 위한 ACK, 연결 설정과 해제에 사용되는 RST, SYN, FIN, 데이터를 상위 계층에게 즉시 전달해야 한다는 의미의 PSH, 송신 측 상위 계층 개체가 '긴급'으로 표시하는 데이터임을 가리키는 URG

순서 번호와 확인응답 번호

  • 순서번호는 세그먼트 순서 번호가 아니라 세그먼트 내의 바이트에 대한 번호임
    • 그니까 100바이트 짜리 세그먼트 3개를 보내면 #0이 0번째 세그먼트를 가리키는게 아니라 0번째 세그먼트의 0번째 바이트를 가리키는 것
    • 그래서 100바이트 짜리 세그먼트 3개를 보내면 응답값음 #100, #200이렇게 올거임
  • 이 순서번호를 가지고 아래와 같은 두 가지 선택지가 있음
    • 순서가 바뀌면 바뀐거 다 버리기 GBN
    • 순서가 바뀌면 임시보관 하고 순서 채우기 위해 기다리기 SR

3.5.3 - 왕복 시간(RTT) 예측과 타임아웃

  • 타임 아웃은 '세그먼트 전송 - 확인응답 받기' 값 보다는 좀 커야할테지만 얼마나 커야 하며 어떻게 측정될까?

왕복 시간 예측

  • Sample RTT - 세그먼트가 송신된 시간~긍정응답이 도착한 시간
    • 재전송된 세그먼트는 제외함
  • EstimatedRTT - Sample RTT의 평균
  • TimeoutInterval = EstimatedRTT + DevRTT(Sample RTT와 EstimetedRTT로 어떤 마진 값을 구한거)

3.5.4 - 신뢰적인 데이터 전송

  • 각 소켓마다 송신 버퍼와 수신 버퍼를 갖고 있음
    • 송신 버퍼는 수신 응답이 오기 전 까지 재전송에 대비해서 보낸 패킷을 갖고 있다가 수신 했다고 확인 되면 그 패킷을 지움
    • 수신 버퍼는 순서 맞을 때 까지 버퍼에서 갖고 있다가 순서 맞으면 상위 계층으로 올려보냄(근데 순서 맞다고 무조건 올려보내는건 아니고 애플리케이션 계층이 read하면 수신되고 순서 맞는것까지 올려보냄)

빠른 재전송

  • 기본적으로 timer 재면서 타임아웃 되면 재전송하고, 타임 아웃 되기 전에 중복 응답 4번 오면 그거 빠르게 재전송함

3.5.5 - 흐름제어

  • 송신자가 수신자의 버퍼를 오버플로시키는 것을 방지하기 위해 속도를 일치시키는 서비스
  • 수신측에서 가용한 버퍼 공간이 얼마나 되는지를 송신자에게 응답값에 포함시켜 알려줌 그럼 송신자는 이를 고려해서 윈도를 조절함
  • 문제점
    • 수신 버퍼가 꽉차서 남은 윈도가 0이라고 응답함 -> 송신측은 송신을 멈추고 기다림
    • 근데 수신측 호스트가 write를 안해서 송신측으로 보내는 세그먼트가 없어서 송신측은 무한정 기다림 -> 데드락
  • 위 문제를 해결하기 위해 일정시간마다 다음 세그먼트의 1파이트만 넣어서 보냄 -> 응답값에 남은 윈도보고 다음 패킷부터 송신 윈도 조절해서 보냄
  • 세그먼트의 맥시멈 크기를 어떻게 정할래?
    • 1) 최대한 크게 -> 속도는 빠르지만 송신측 애플리케이션의 write가 느리다면...? 최대치만큼 기다릴거니..?
    • 2) 최대한 작게 -> 보내는건 계속 보내겠지만 오버헤드가...ㄷㄷ;;
    • 해결책
      • write됐을 때 양이 적더라도 일단 보내자!
      • 그리고 보낸거에 대해 응답값이 오면 그때 모인거 까지 보내자!
      • 만약 응답값이 아직 안왔더라도 최대 크기까지 모였다면 그것도 보내자!

3.5.6 - TCP 연결 관리

연결(세 방향 핸드셰이크)

  • 1단계 : 클라이언트 측 TCP는 서버측 TCP에게 데이터를 포함하지 않은 SYN세그먼트를 보낸다(SYN플래그를 1로 설정한 세그먼트)
  • 2단계 : TCP SYN을 받은 서버도 데이터를 포함하지 않은 연결 승인 세그먼트를 클라이언트로 보낸다(SYN플래그를 1로 설정한 세그먼트)
    • SYN플래그 말고도 확인 응답 필드는 client_isn+_1로 설정하고 송신할 정보의 최초 번호도 보냄
  • 3단계 : 연결 승인 세그먼트를 확인했다는 응답 세그먼트를 보내며 이때는 SYN을 0으로 설정하고 여기서부터 데이터 포함 가능

종료

  • 클라이언트 애플리케이션 프로세스가 연결 종료 명령을 내리고 FIN이 1로 설정된 세그먼트를 서버에게 보냄
  • 서버는 수신하고 FIN을 1로 설정해 확인 응답을 보냄
  • 마지막으로 클라이언트는 서버의 종료 세그먼트에 확인 응답을 함

[3.6] 혼잡 제어의 원리

  • 네트워크 혼잡 원인을 처리하기 위해 네트워크 혼잡을 일으키는 송신자들을 억제하는 메커니즘이 필요하다!

3.6.1 - 혼잡의 원인과 비용

시나리오 1 : 2개의 송신자와 무한 버퍼를 갖는 하나의 라우터

  • 라우터의 버퍼가 무한해도 호스트 A,B의 전송률이 라우터가 소화할 수 있는 전송률에 가까워 질 수록 지연 발생

시나리오 2 : 2개의 송신자, 유한 버퍼를 가진 하나의 라우터

  • 가정
    • 버퍼가 가득 찼을 때 도착한 패킷은 버려진다
    • 각 연결은 신뢰적이어서 라우터에서 버려지면 재전송 될 것이다
  • 손실
    • 버퍼의 오버플로 때문에 drop되면 drop된걸 다시 보내야함
    • 그리고 drop된게 아니라 큐잉 지연때문에 '아직' 수신측으로 도착안한건데 타임아웃 터지면서 똑같은걸 또 보내면 또 버퍼에서 드롭되거나 똑같은게 버퍼에 들어가 있다거나 아주 그냥 난리가 남

시나리오 3 : 4개의 송신자와 유한 버퍼를 갖는 라우터, 그리고 멀티홉 경로

  • A -> C로 보내는데 1번 라우터 2번 라우터를 거친다. 근데 2번 라우터 앞에 B가 있어서 이미 B의 데이터로 가득차있다고 가정
    • A가 보낸 패킷이 1번라우터를 통과해 2번 라우터에서 drop되면 결국 다시 1번 라우터로 보내는 일을 반복해야하며 1번 라우터를 통과하는 작업 자체가 의미없는 일이 되어버림

3.6.2 - 혼잡 제어에 대한 접근법

  • 가장 크게, 네트워크 계층이 혼잡 제어를 목적으로 트랜스포트 계층에게 직접적인 도움을 제공하는지에 따라 구별
    • 종단 간의 혼잡 제어
      • 네트워크 계층은 도움주지 않고 관찰된 네트워크 동작에 의해 추론(패킷 손실 및 지연)
      • 네트워크 손실은 혼잡 발생 표시로 간주하고 윈도 크기를 줄임
      • 증가하는 왕복 지연값을 네트워크 혼잡 증가 지표로 활용
    • 네트워크 지원 혼잡 제어
      • 라우터들이 송/수신자에게 직접적인 피드백을 제공(전송률 등을 명확하게 알릴 수 있게 함)
      • 초크 패킷의 형태를 갖는다

[3.7] TCP 혼잡 제어

3.7.1 - 전통적인 TCP의 혼잡 제어

  • 네트워크 혼잡에 따라 연결에 트래픽을 보내는 전송률을 각 송신자가 제한하도록 하는 것
  • 혼잡이 없을 감지하면 송신자는 송신율을 높이고 혼잡을 감지하면 송신율을 줄인다
  • 의문점
    • 전송률을 어떻게 제한하는가?
      • 혼잡 윈도(congestion window, cwnd)를 조절하여 데이터를 전송하는 속도를 조절
    • 혼잡을 어떻게 감지하는가?
      • 손실된 세그먼트는 혼잡을 의미하면 송신율 줄여라
      • 중복 ACK가 온다는건 이전에는 느렸어도 지금은 잘 통신된다는거니 전송률을 높여도 된다
    • 어떤 알고리즘을 사용해야 하는가?
      • 천천~히 늘리다가 혼잡 발견되면 확! 줄이기!
      • 슬로 스타트
        • cwnd는 일반적으로 1MSS로 초기화 된다
        • 1MSS보내고 응답 올 때마다 2배씩 늘린다
        • 손실 이벤트가 있으면 다시 1로 줄이고 ssthresh(슬로 스타트 임곗값)을 cwnd/2로 정한다
        • ssthresh에 도달하면 2배가 아니라 혼잡 회피 상태로 들어간다
        • 만약 3개의 중복 ACK가 검출되면 빠른 회복 상태로 들어간다
      • 혼잡 회피
        • cwnd를 두 배로 증가시키기보다는 보수적으로 증가시킴
          • 1/10MMS만큼씩 혼잡 윈도를 증가시키고 모든 10개의 세그먼트가 수신되었을 때의 ACK이후 하나의 MSS만큼만 혼잡 윈도 값을 증가 시킨다
        • 언제 증가가 끝날지는 슬로 스타트랑 동일함
          • 손실 이벤트가 있으면 다시 1로 줄이고 ssthresh을 cwnd/2로 정한다
        • 3개의 중복 ACK을 수신한 시점에는 swnd의 값을 반으로 줄이고 ssthresh값을 swnd의 반으로 기록하고 빠른 회복 상태로 들어감
      • 빠른 회복
        • cwnd값을 손실된 세그먼트에 대해 수신된 모든 중복된 ACK에 대해 1MSS만큼씩 증가시킨다
        • 손실된 세그먼트에 대한 ACK가 도착하면 혼잡 회피 상태로 들어간다
        • 만약 타임아웃이 발생하면 슬로 스타트나 혼잡 회피에서와 같은 동작을 수행한 후 슬로 스타트로 전이한다
          • 즉, 1로 줄이고 ssthresh을 cwnd/2로 정한다
        • 빠른 회복은 필수 선택은 아님(TCP 타호는 채택 x, TCP리노는 채택함)
    • TCP 큐빅 - TCP리노보다 혼잡 지점까지 더 빠르게 늘림

3.7.2 - 네트워크 지원 명시적 혼잡 알림과 지연 기반 혼잡 제어

  • TCP송신자는 네트워크에서 명시적인 혼잡 표시를 수신하지 않는 대신 관찰된 패킷 손실을 통해 혼잡을 추론했지만 최근에는 네트워크가 TCP송신자와 수신자에게 명시적으로 혼잡 신호를 보낼 수 있도록 제안, 구현 및 배포되었다

명시적 혼잡 알림

  • ECN(Explicit Congestion Notification)
    • TCP와 IP가 모두 관련되어 있음
    • 네트워크 계층에서 IP데이터그램 헤더 필드에 있는 2비트가 ECN에 사용되며 라우터에서 사용됨
    • 혼잡해지는 라우터는 그 라우터에서 버퍼가 가득 차서 패킷들이 삭제되기 전에 송신자에게 혼잡 시작을 알리는 혼잡 알림 비트를 설정할 수 있음

지연 기반 혼잡 제어

  • 지연 기반 접근 방식을 취하여 패킷 손실이 발생하기 전에 혼잡 시작을 사전에 감지하는 것
  • TCP베가스는 실제 송신자가 측정한 처리량이 이 값에 가까우면 경로가 아직 정체되지 않았고 전송 속도 증가 가능
  • 실제 송신자가 측정한 처리량이 혼잡하지 않을 때의 처리율 보다 현저히 낮으면 경로가 혼잡하고 송신자는 전송 속도를 낮추게 된다
  • TCP 송신자가 파이프를 가득 채우되 그 이상으로 채우지 않도록 해야한다!
  • BBR혼잡 제어 프로토콜은 TCP베가스의 아이디어를 기반으로 하며 TCP와 공정하게 경쟁할 수 있는 메커니즘을 통합
    • 구글 및 유튜브 웹 서버에도 베포되고 있음

3.7.3 - 공평성

  • 한 네트워크에 연결된 TCP의 전송률을 계산해보니 각 TCP들의 전송률이 조정되면서 1/n으로 공평하다~ 이런 얘기
  • 호스트 수가 아니라 TCP연결 수에 따라 조정됨
    • 예를 들어 A호스트가 TCP1개, B호스트가 TCP3개 연결 했고 네트워크의 전송률이 100이라고 가정했을 때
    • A호스트가 50, B호스트가 50분배받고 B호스트의 TCP들이 50을 3으로 나누는게 아니라 그냥 그 네트워크에서 연결된 TCP들의 수 만큼 나눠져서 각 TCP가 약 25의 전송률을 얻음
  • UDP는 네트워크 혼잡을 고려하지 않고 그냥 냅다 들이부어 버리기 때문에(유실을 신경을 안써서;;) 네트워크가 혼잡해질 수 있음

[3.8] 트랜스포트 계층 기능의 발전

QUIC : 빠른 UDP 인터넷 연결

  • 두 종단 사이에 신뢰적이고 혼잡 제어된 데이터 전송을 제공하는 애플리케이션 계층 프로토콜
  • 이미 널리 배포되었지만 아직 표준화되는 과정에 있으며 구굴은 본인들 웹 서버에 배포함.
  • 오늘날 인터넷 트래픽의 7%이상이 QUIC를 이용함
  • UDP를 하위 트랜스포트 계층 프로토콜로 사용하는 애플리케이션 계층 프로토콜이며 HTTP/2버전 위에서 인터페이스되도록 설계되었다.
  • 가까운 장래에 HTTP/3은 기본적으로 QUIC를 통합할 것
  • 특징
    • 연결지향적이고 안전함 : TCP같이 두 종단 간의 연결 지향 프로토콜임
    • 스트림 : QUIC연결이 설정되면 새 스트림을 빠르게 추가할 수 있음
    • 신뢰적이고 TCP친화적인 혼잡 제어 데이터 전송 : TCP리노 프로토콜을 약간 수정한 TCP뉴리노를 기반으로 함