[CS/ Network] 컴퓨터 네트워킹 하향식 접근 8판 3장 트렌스포트 계층 3.5 연결지향형 트랜스포트: TCP 206

yujeongkwon·2023년 8월 24일
0

CS / Network

목록 보기
15/27

3.5 연결지향형 트랜스포트: TCP 206
3.5.1 TCP 연결 207
3.5.2 TCP 세그먼트 구조 209
3.5.3 왕복시간(RTT) 예측과 타임아웃 214
3.5.4 신뢰적인 데이터전송 217
3.5.5 흐름제어 224
3.5.6 TCP 연결 관리 227

🤝🏻 3.5.1 TCP 연결

  • '핸드셰이크’-> 연결지향형
  • 데이터 전송을 보장하는 파라미터들을 각자 설정하기 위한 어떤 사전 세그먼트들 전송
  • TCP 연결 설정의 일부로서,연결의 양단은 많은 TCP 상태 변수를 초기화
  • TCP '연결’은 논리적인 것 : 두 통신 종단 시스템의 TCP에 존재하는 상태 공유
    • 물리적인 것X (회선 교환 네트워크-TDM이나 FDM와 같은)
    • 오직 종단 시스템에서만 동작하고 중간의 네트워크 요소(라우터,링크 계층 스위치)에서는 동작X,중간의 네트워크 요소들은 TCP 연결 상태 유지 X(감지도 못함)
  • 전이중 서비스(ftiU-duplex service)
  • 점대점(point-to-point) : 멀티캐스팅 불가 only 1:1
  • 연결 설정 법
    • 연결을 조기화하는 프로세스를 클라이언트 프로세스, 다른 것을 서버 프로세스
    1. 클라이언트 프로세스가 서버에게 연결 요청
      clientsocket. connect ((serverName, serverPort) )
    2. 클라이언트의 트랜스포트 계층은 서버의 TCP와의 TCP 연결 설정을 진행
      • 클라이언트가 먼저 특별한 TCP 세그먼트를 전송함
    3. 서버는 두 번째 특별한 TCP 세그먼트로 응답
    4. 클라이언트가 세 번째 특별한 세그먼트로 다시 응답
      - 처음 2개의 세그먼트에는 페이로드(애플리케이션 계층 데이터)가 없다.
      • 세 번째 세그먼트는 페이로드 포함 가능
      • 3개의 세그먼트 전송 -> 세 방향 핸드셰이크
    5. 서로 데이터 통신 가능
  • 데이터 통신에서는~?
    • 클라이언트 프로세스는 소켓(프로세스의 관문)을 통해 데이터의 스트림 전달
    • 소켓을 지나면 데이터는 클라이언트에서 동작하고 있는 TCP에 맡겨짐
    • 그림 3.28처럼 TCP는 초기 세 방향 핸드셰이크 동안 준비된 버퍼중의 하나인 연결의 송신 버퍼로 데이터를 전송
    • 때때로 TCP는 송신 버퍼에서 데이터 묶음을 만들어서 네트워크로 보낸다.
      • TCP가 언제 버퍼된 데이터를 전송할지는 정의X 멋대로 보내라!
      • 세그먼트로 모아 담을 수 있는 최대 데이터의 양은 maximum segment size(MSS)로 제한
      • MSS는 일반적으로 로컬 송신 호스트에 의해 전송될 수 있는 가장 큰 링크 계충 프레임의 길이(maximum transmission unit, MTU)에 의해 일단 결정
      • 그 후, TCP 세그먼트(IP 데이터그램 안에 캡술화되었을 때)와 TCP/IP 헤더 길이(통상 40바이트)가 단일 링크 계층 프레임에 딱 맞도록 하여 정해짐
      • 이더넷과 PPP 링크 계층 프로토콜은 모두 1,500바이트의 MTU를 가짐
        => MSS의 일반적인 값은 1460바이트
      • MSS가 헤더를 포함하는 TCP 세그먼트의 최대 크기가 아니라,세그먼트에 있는 애플리케이션 계층 데이터에 대한 최대 크기라는 점을 주의
  • TCP 세그먼트 = TCP 헤더 + 클라이언트 데이터
  • 세그먼트는 네트워크 계층에 전달 -> 네트워크 계층 IP 데이터그램 안에 각각 캡슐화
    -> 이 세그먼트들은 네트워크로 송신 -> TCP가 상대에게서 세그먼트를 수신했을 때,그림 3.28처럼 세그먼트의 데이터는 TCP 연결의 수신 버퍼에 위치 -> 애플리케이션은 이 버퍼로부터 데이터의 스트림을 읽음
  • 연결의 양 끝은 각각 자신의 송신 버퍼와 수신 버퍼를 가짐
  • TCP 연결은 한쪽 호스트에서의 버퍼,변수,프로세스에 대한 소켓 연결과 다른 쪽 호스트에서의 버퍼,변수,프로세스에 대한 소켓 연결의 집합으로 이루어짐



💊 3.5.2 TCP 세그먼트 구조

  • 헤더 필드와 데이터 필드로 구성
  • 데이터 필드는 애플리케이션 데이터의 일정량을 담음
    • 일반적으로 MSS 크기로 파일을 분할
    • 대화식 애플리케이션은 MSS보다 작은 양의 데이터를 전송
      • ex) 원격 로그인(텔넷과 ssh)에서는 종종 데이터 필드는 오직 1바이트
  • TCP 헤더는 일반적으로 20바이트
    • UDP 헤더보다 12바이트 큼
    • ex) 텔넷과 ssh에 의해 전송되는 세그먼트는 단지 21바이트 길이
  • TCP 세그먼트 구조는 UDP에도 있는 아래 2개 포함
    • 출발지, 목적지 포트 번호 : 상위 계층으로부터 다중화와 역다중화를 하는 데 사용
    • 체크섬 필드
  • +) 추가 필드들
    • 32비트 순서 번호 필드, 32비트 확인웅답 번호 필드
      • 신뢰적인 데이터 전송 서비스 구현에서 TCP 송신자와 수신자에 의해 사용
    • 16비트 수신 윈도우 필드 : 흐름 제어에 사용
      • 이는 수신자가 받아들이려는 바이트의 크기를 나타내는 데 사용
    • 4비트 헤더 길이 필드 : 32비트 워드 단위로 TCP 헤더의 길이를 나타냄
      • TCP 헤더는 TCP 옵션 필드 때문에 가변 길이가 될 수 있다
      • 일반적으로는 옵션 필드는 일반적인 TCP의 길이가 20바이트가 되도록 비어 있음
    • 옵션 필드 : 선택적이고 가변적임
      • 송, 수신자가 최대 세그먼트 크기(MSS)를 협상
      • 고속 네트워크에서 사용하기 위한 윈도 확장 요소로 이용
      • 타임 스탬프 옵션도 정의
    • 6비트 플래그 필드
      • ACK 비트 : 성공적으로 수신된 세그먼트에 대한 확인응답
      • RST, SYN, FIN 비트 : 연결 설정과 해제에 사용
      • PSH 비트 : 수신자가 데이터를 상위 계층에 즉시 전달해야한다는 것을 가리킴
      • URG 비트 : 송신 측 상위 계층 개체가 ‘긴급’으로 표시하는 데이터임을 가리킴
    • 16비트 긴급 데이터 포인터 필드 : 긴급 데이터의 마지막 바이트의 위치를 가리킴
      • TCP는 긴급 데이터가 존재할 때 수신 측 상위 계층 개체에게 통지
      • 긴급 데이터의 끝에 대한 포인터를 전달



⭐순서 번호와 확인응답 번호

  • 순서 번호

    • TCP는 데이터 구조화X, 단지 순서대로 정렬되어 있는 바이트 스트림으로 봄.
    • 일련의 전송된 세그먼트에 대해X, 전송된 바이트의 스트림에 대해!
    • 순서 번호 = 세그먼트에 있는 첫 번째 바이트의 바이트 스트림 번호
    • ex) 데이터 스트림 : 500,000 바이트, MSS 1,000바이트 -> 500개 세그먼트
      -> 순서번호 : 0, 1,000, 2,000 ~
  • 확인 응답 번호

    • TCP는 전이중 방식
    • 수신자가 자신의 세그먼트에 삽입하는 확인응답 번호는 수신자가 송신자로부터 기대하는 다음 바이트의 순서번호
    • 만약 수신자가 0~535바이트와 900~1,000 바이트의 세그먼트를 수신했을 때, 536 ~899 바이트 세그먼트를 수신하지 못함 -> 그럼 수신자는 536 확인 응답 번호를 넣음
    • 이때 TCP는 스트림에서 첫 번째 잃어버린 바이트까지의 바이트들까지만 확인응답하기 때문에,TCP는 누적 확인응답을 제공한다고 함
    • 위 처럼 순서가 틀리게 도착했다면?
      • TCP 구현 개발자 맘대로~
        (1) 수신자가 순서가 바뀐 세그먼트를 즉시 버린다(설계 단순화)-> GBN
        (2) 수신자는 순서가 바뀐 데이터를 보유하고,빈 공간에 잃어버린 데이터를 채우기 위해 기다린다. -> SR
      • 후자가 네트워크 대역폭 관점에서는 효율적이며,실제에서도 취하는 방법
  • 그림 3.30에서 시작 순서 번호가 0이라고 가정

    • 실제로는 TCP 연결의 양쪽 모두 시작 순서 번호를 임의로 선택
    • 이것은 두 호스트 사이에 연결이 종료된 후, 나중에 다시 연결(이전과 같은 포트할 때, 아직 네트워크에 남아 있던 세그먼트가 유효한 세그먼트로 오인될 확률을 최소화

+)

  • Piggyback 방식
    : 수신측에서 수신된 데이터에 대한 확인 응답을 즉시 보내지 않고, 별도의 제어 프레임도 사용하지 않은 채, 전송할 데이터가 있는 경우에만, 그 데이터 프레임 안에 확인 필드를 덧붙여 전송하는 기법
    : 데이터 보내는김에~ 확인응답도 실어보낸다는 뜻~~ -> 둘이 같이하니까 효율적~

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

  • TCP가 손실 세그먼트를 발견하기 위해 타임아웃/재전송머 커니즘을 사용
  • 타임아웃 주기는 우쨰?
    • 타임아웃 > 세그먼트가 전송된 시간부터 긍정 확인응답될 때까지의 시간인 연결의 왕복 시간(Rround-trip time, RTT)
    • ㄴ그렇지 않으면, 불필요한 재전송이 발생
  • 알아보자~~

왕복 시간예측

  • 세그먼트에 대한 RTT 샘플(SampleRTT) : 세그먼트 송신 시간~긍정응답이 도착한 시간까지의 시간 길이
  • 모든 세그먼트의 SampleRTT를 측정X -> 대부분의 한 번에 하나의 SampleRTT 측정
    = 이는 대략 왕복 시간마다 SampleRTT의 새로운 값을 얻음
  • 재전송한 세그먼트에 대한 SampleRTT는 계산X, 한 번 전송된 세그먼트만 측정
  • RTT를 추정하기 위해 SampleRTT 값의 평균값을 채택
    • SampleRTT 값은 라우터에서의 혼잡과 종단 시스템에서의 부하 변화 때문에 세그
      먼트마다 불규칙적
  • 긍정 확인응답을 수신하고 새로운 SampleRTT를 획득하자마자 TCP는 다음 공식에 따라 EstimatedRTT를 갱신
    • EstimatedRTT는 SampleRTT 값의 가중평균임
      • 예전 샘플보다 최근 샘플에 높은 가중치를 줌
        => 최신 샘플들이 네트워크상의 현재 혼잡을 더 잘 반영하기 때문에
    • 이런 평균을 지수적 가중 이동 평균(EWMA)라고 함.
      - 주어진 SampleRTT의 가중치가 갱신 절차가 진행됨에 따라 빠르게 지수적으로 감
      소하므로
      EstimatedRTT=(1-α)EstimatedRTT+αSampleRTT(a = 0.125)
  • RTT의 예측 외에 RTT의 변화율을 측정하는 것도 매우 유용
    • DevRTT : RTT의 변화율
    • ㄴ SampleRTT가 EstimatedRTT로부터 얼마나 많이 벗어나는지에 대한 예측으로 정의
    • DevRTT는 SampleRTT와 EstimatedRTT 값 차이의 EWMA임을 유념
    DevRTT = (1 - b) * DevRTT + b * | SampleRTT - EstimatedRTT |



재전송 타임아웃 주기의 설정과 관리

  • 타임아웃 주기는 EstimatedRTT보다 크거나 같아야 하지만 너무 커도 안 됨.
    • 너무 크면 세그먼트를 잃었을 때,TCp는 세그먼트의 즉각적인 재전송을 못함
      => 데이터 전송 지연
  • => 타임아웃 주기 = EstimateRTT에 약간의 여윳값을 더한 값으로 설정
  • SampleRTT 값에 변동이 클 때는 여윳값을 크게
  • SampleRTT 값에 변동이 작을 때는 여윳값을 작게
  • ㄴ-> DevRTT의 값이 역할을 하게 된다
    Timeoutlnterval = EstimatedRTT + 4 * DevRTT
  • 초기 Timeoutinterval의 값으로 1초를 권고
  • 타임아웃이 발생하면, Timeoutinterval의 값은 두 배로 하여 조만간 확인 응답할 후속 세그먼트에게 발생할 수 있는 조기 타임아웃을 피하도록 함
    • -> 세그먼트가 수신 되고 EstimatedRTT가 수정되면 다시 공식대로 재정립

📨 3.5.4 신뢰적인 데이터 전송

  • TCP는 IP의 비신뢰적인 최선형 서비스에서 신뢰적인 데이터 전송 서비스를 제공
    • 손상 X, 손실X, 중복 X, 순서 보장
    • = 바이트 스트림은 송신자가 전송한 것과 같은 바이트 스트림
  • 위에서는 각각의 세그먼트와 개별적인 타이머가 한 쌍이 되어 동작한다고 가정
    • 오버헤드 졸라 큼
    • -> 확인응답 없는 다수의 세그먼트들이 있다고 하더라도,단일 타이머 사용
  • 송신자가 TCP 흐름 또는 혼잡 제어의 제약을 받지 않고, 데이터가 크기가 MSS보다 작으며, 데이터 전송이 한 방향으로만 있다고 가정
  • 송신자의 데이터 전송/재전송에 관련된 주요 이벤트 :
    1. 상위 애플리케이션으로부터 수신된 데이터
    1. 타이머 타임이웃
    2. ACK 수신
NextSeqNum = InitialSeqNumber
SendBase = InitialSeqNumber

while (true) {
    switch (event) {
    /* 
   TCP는 애플리케이션으로부터 데이터를 받고,세그먼트로 이 데이터를 캡슐화하고,IP에게 이 세그먼트를 넘김.
   + 바이트이 바이트 열 번호를 순서 번호로 포함.
   + 타이머가 이미 다른 세그먼트에 대해 실행 중이 아니면,이 세그먼트를 IP로 넘길 때 타이머를 시작 
   	  ㄴ= 타이머는 확인되지 않은 가장 오래된 세그먼트를 쨰깎쨰깎
      ㄴ 타이머 만료 주기는 Timeoutinterval
    */
        case DATA_RECEIVED_FROM_APPLICAION_ABOVE:
            create TCP segment with sequence number NextSeqNum
            if (timer not currently running)
                start timer
            pass segment to IP
            NextSeqNum += length(data)
            break;
            
	/*
    타임아웃 이벤트에 대해 타임아웃을 일으킨 세그먼트를 재전송하여 응답
    -> 그 후, TCP의 타이머 다시 시작
    */
        case TIMER_TIMEOUT:
            retransmit not-yet-acknowledged segment with smallest sequence number
            start timer
            break;
            
	/*
    수신자로부터의 수신 확인응답 세그먼트(ACK) 수신
    변수 SendBase와 ACK 값 y를 비교
       - TCP 상태 변수 SendBase : 수신 확인응답이 확인되지 않은 가장 오래된 바이트의 순서 번호
       (+ SendBase-1 = 수신자에게서 정확하게 차례대로 수신되었음을 알리는 마지막 바이트의 순서 번호)
       - 누적 확인응답 사용 => y는 y바이트 이전의 모든 바이트의 수신 확인
       - 만일 y〉SendBase이면,ACK는 이전에 확인응답 안 된 하나 이상의 세그먼트들을 확인한 것
       => 송신자는 자신의 SendBase 변수를 갱신
       - 아직 확인응답 안 된 세그먼트들이 존재한다면 타이머 재시작
    */
        case ACK_RECEIVED_WITH_ACK_FIELD_VAIUE_OF_y:
            if (y > SendBase) {
                SendBase = y
                if (not-yet-acknowledged segments exist)
                    start timer
            }
            break;
    }
}

몇 가지 흥미로운 시나리오
1. 송신자가 순서번호 92를 보냈는데 수신자의 확인응답이 손실됨 -> 송신자 재전송 -> 수신자가 수신햇는데 이미 받은거니까 걍버리고 다시 그 세그먼트 확인응답 줌
2. 송신자가 연속해서 두 세그먼트 전송 -> 수신자가 둘다 잘 받음 -> 확인응답 보냄 -> but 송신자의 타임아웃 기간동안 못옴 -> 송신자 첫번쨰거 다시 보냄 -> 타임아웃 전 2번로 보낸 세그먼트 응답옴 -> 송신자: ㅇㅋㅇㅋ 둘다 잘갔구나 2번째 재전송안할게~
3. 2번째랑 똑같은데 수신자의 첫번째 확인응답 손실, 2번째 확인응답 잘감 -> 송신자 ㅇㅋㅇㅋ 잘갔구나 암것도 재전송 안할게~


타임이웃 주기의 두 배로 설정

  • 타임아웃이 발생할 때마다 TCP는 앞에서 설명한 것처럼 아직 확인응답이 안 된 가장 작은 순서 번호를 가진 세그먼트를 재전송 -> 이때 타임 아웃 주기를 이전 값의 두 배로 설정
    • 마지막 EstimatedRTT와 DevRTT로부터 타임아웃 값 설정X
    • 주기는 각 재전송 후에 지수적으로 증가
    • but 다른 두 가지 이벤트(상위의 애플리케이션으로부터 데이터 수신 or ACK 수신) 이후 타이머가 시작될 때는 TimeoutInterval은 EstimatedRTT와 DevRTT의 가장 최근의 값에서 가져옴
  • 요고시 바로 혼잡제어
    • 타이머 종료 = 주로 네트워크에서의 혼잡때매 발생
    • = 출발지와 목적지 사이의 경로에서 하나 이상의 라우터 버퍼에 도착한 많은 패킷
      은 패킷의 손실이나 오랜 큐 대기의 원인
    • 혼잡할 때 출발지에서 지속해서 패킷의 재전송 -> 엉망이징창이
    • 따라서 TCP는 송신자가 더 긴 간격으로 재전송

빠른 재전송

  • 타임아웃이 유발하는 재전송의 한 가지 문제는 타임아웃의 주기가 길 수도 있음
    • = 세그먼트를 잃었을 때,긴 타임아웃 주기는 잃어버린 패킷을 다시 보내기 전에 송신자를 오랫동안 기다리게 해서 종단 간의 지연을 증가시킴
    • ㄴ-> 송신자는 종종 중복된 ACK을 통해 타임아웃 전, 패킷 손실 파악 가능
  • 송신자가 5개의 세그먼트를 보냄 -> 2번째 세그먼트 손실 -> 4개 수신, 2번째가 손실된 거 암 -> 2번째 손실됐으니까 빠뜨린 2번말고 다른거 3개 왔을때 2번달라고 중복 ACK 3번 각각 보냄 -> 송신자 중복 3번온거보고 ACK에 적힌 순서번호 다시보내달라는 거지?? 해서 타임 아웃전 재전송 = 빠른 재전송

2번째까지 중복 재전송은 순서가 바뀐것일 수 도 있으니까 대기타다가 3번쨰 응답받자마자 손실이구나 알고 재전송하는거래 '3번'이 오면 손실 확인하구 빠른 재전송 ㅇㅇ

+) 표 3.2 TCP ACK 생성권고
표 3.2 TCP ACK 생성 권고

  • 빠른 재전송을 하는 TCP
// Event: ACK 수신, ACK 필드 값이 y인 경우
if (y > SendBase) {
    SendBase = y;

    // 아직 ACK되지 않은 세그먼트가 있는 경우 타이머 시작
    if (아직 ACK되지 않은 세그먼트가 있는지 확인) {
        타이머_시작();
    }
	else {
    // 이미 ACK된 세그먼트에 대한 중복 ACK
    중복_ACK_수신_횟수_증가(y);

    	// y에 대한 중복 ACK 수가 3인 경우 TCP 빠른 재전송
    	if (y에_대한_중복_ACK_수 == 3) {
        	// 시퀀스 번호가 y인 세그먼트 재전송
        	segment_재전송(y);
        }
     break;
    }
}

GBN인가 SR인가?

  • TCP는 둘중에 뭐임?
    • TCP 확인응답은 누적되고 올바르게 수신, 순서 잘못된 것은 개별 ACK를 받지 않음
    • TCP는 송신자는 전송했지만 확인응답 안 된 바이트의 가장 작은 순서 번호(SendBase)와 전송될 다음 바이트의 순서 번호(NextSeqNum)를 유지
    • GBN이랑 비슷해보이지? 근데 아님, 차이점 ㄱ
      • TCP는 정확하지만 순서바뀐 것들을 버퍼링함 = N개중에 1개(n이라는 패킷) 손실
        -> 순서번호 n인 세그먼트 1개만 재전송
        +) TCP는 세그먼트 n에 대한 타임아웃 전에 세그먼트 n + 1에 대한 긍정 확인응답이 도착한다면 세그먼트를 재전송X (? 왜죠? 손실이 아니라 순서만 이상한 경운가?)
      • GBN은 n부터 n+1, n+2 ... N 까지 다 재전송
    • TCP에 수정 제안된 선택적 확인응답 : TCP 수신자가 마지막으로 올바로 수신된 ‘순서가 맞는’ 세그먼트에 대해 누적 확인응답을 하기보다는 ‘순서가 틀린’ 세그먼트에 대해 선택적으로 확인응답
      • = 선택적 재전송과 결합했을 경우(이미 수신자가 선택적 확인응답을 한 세그먼트의 개전송은 제외),TCP는 원래의 SR 프로토콜과 매우 유사
  • 결론 : TCP 오류 복구 매커니즘은 GBN 이랑 SR 프로토콜 혼합으로 보자~

stop-and-wait 종단 간 지연이 많아지므로, pipelining이 나옴
pipelining의 문제 해결법 두가지는 GBN, SR

  • Go-Back-N(GBN)과 Select Repeat(SR)
    Go-Back-N(GBN) 기법과 Select Repeat(SR) 기법은 모두 에러 복원 기법 중 하나이다.
    • Go-Back-N(GBN) 기법은 전송된 프레임이 손상되면 확인된 마지막 프레임 이후로 보내진 프레임을 재전송하는 기법
      • 프로토콜에서 송신자는 확인응답을 기다리지않고 여러 패킷을 전송할 수 있음
      • 누적 확인응답과 단일 타이머로 패킷이 손실된 부분부터 전부 다시 재전송.
    • Selective Repeat(SR) 기법은 손상되거나 분실된 프레임만을 재전송하는 기법
      • 개별 확인응답을 요구하고, 개별 타이머로, 패킷이 손실된 부분만을 의심하여 그 부분만 다시 재전송 한다.
        손실된 패킷의 이후 패킷은 버퍼에 저장되며, 손실 패킷이 재전송되고 나면 순서에 맞게 버퍼에서 전송된다.

⛵3.5.5 흐름 제어

  • TCP 연결의 각 종단에서 호스트들은 연결에 대한 개별 수신 버퍼를 설정
  • -> TCP 연결이 순서대로 올바르게 바이트를 수신할 때 TCP는 데이터를 수신 버퍼에 저장
  • 애플리케이션이 데이터를 읽는 속도가 비교적 느리면 송신자가 많은 데이터를 빠르게 전송
    -> 연결의 수신 버퍼에 오버플로 발생
  • 이를 방지하기 위해 애플리케이션에게 흐름 제어 서비스 제공
    • : 수신하는 애플리케이션의 읽는 속도와 송신자가 전송하는 속도를 일치 시킴
  • 혼잡제어와 헷갈리지 마~ 동작은 비슷한데 명백히 다른 목적임!
  • TCP의 흐름제어 서비스 제공법 (tcp 수신자가 순서가 바뀐 세그먼트를 버린다고 가정)
    • TCP는 송신자가 수신 윈도우라는 변수를 유지하여 흐름 제어
    • 수신 윈도우 : 수신 측에서 가용한 버퍼 공간이 얼마나 되는지 송신자에게 알려줌.
    • TCP는 전이중 연결 -> 송신자는 별개의 수신 윈도를 유지
    • 파일 전송의 환경에서 수신 윈도
      • 수신자는 이 연결에 수신 버퍼를 할당, RCVBuffer : 수신 버퍼의 크기
      • 시간나는대로 수신자의 애플리케이션 프로세스는 버퍼로부터 데이터를 읽으며 다음과 같은 변수들을 정의
        LastByteRead: 수신자의 애플리케이션 프로세스가 마지막으로 읽은 데이터 스트림의 바이트 번호
        LastByteRcvd: 수신 버퍼에 저장된 데이터 스트림의 마지막 바이트의 번호
      • 오버플로 방지위해 다음 수식 적용
        LastByteRcvd - LastByteRead <= RcvBuffer
      • rwnd : 버퍼의 여유 공간
        rwnd = RcvBuffer - [LastByteRcvd - LastByteRead]
      • 시간에 따라 여유 공간은 변하므로 rwnd는 동적임.
  • rwnd는 어케씀?
    • 수신자가 rwnd 값을 설정함으로써 송신자에게 버퍼 여유공간을 알려줌
    • 수신자가 초기에는 rwnd = RcvBuffer로 설정
    • 이를 위해 수신자는 몇개의 특정 연결 관련 변수들을 유지해야 함
  • 반면에 송신자는 수 LastByteSentLastByteAcked 변수를 유지
    • 수신자가 전송 확인응답 안 된 데이터의 양 : LastByteSent-LastByteAcked
    • rwnd 보다 작은 확인응답 안 된 데이터 양을 유지함으로써 오버플로 발생X
      LastByteSent 一 LastByteAcked <= rwnd
  • 작은 문제 발생
    • rwnd가 0으로 가득 찼을 때, 수신자가 송신자에게 말해줄게 없음. -> 수신자가 후에 버퍼를 비워도 송신자에게 말할게없음 -> 송신자는 버퍼 빈거 모름 -> 데이터 전송 불가
    • 문제 해결 : 송신자가 수신자의 수신 윈도우가 0일때, 1 바이트 데이터로 세그먼트(수신자에겐 긍정 확인 응답과 같음)를 계속해서 전송하도록 요구 -> 수신자는 버퍼를 비우고 0 이아닌 rwnd 값을 넣어 긍정확인응답 보냄
  • UDP는 냅다 때려박고 오버플로나면 세그먼트 다 잃어버림 ㅋㅋ


🔎 3.5.6 TCP 연결 관리

  • SYN 플러드(flood)공격을 비롯한 가장 일반적인 네트워크 공격의 대부분은 TCP 연결 관리의 취약점을 악용 -> TCP 연결관리 중요함~
  • 클라이언트가 서버에 연결 요청 가정
    -> 클라이언트 애플리케이션 프로세스는 서버에 있는 프로세스와 연결 설정하기를 원한다는 것을 클라이언트 TCP에게 알림
    -> 클라이언트 안의 TCP는 다음과 같은 방법으로 TCP를 이용해 서버와 TCP 연결 설정을 시작
    • 1단계: 먼저 클라이언트 측 TCP는 서버 TCP에게 특별한 TCP 세그먼트를 송신
      • 이 특별한 세그먼트는 애플리케이션 계층 데이터를 포함X
      • 세그먼트의 헤더에 SYN 비트라고 불리는 하나의 플래그 비트를 1로 설정
        ㄴ>이 특별한 세그먼트를 SYN 세그먼트라고 부름.
      • 추가로 클라이언트는 최초의 순서 번호(client_isn)를 임의로 선택하고,최초의 TCP SYN세그먼트의 순서 번호 필드에 이 번호를 넣음
        ㄴ> 이 세그먼트는 IP 데이터그램 안에서 캡술화되고 서버로 송신 됨.
      • 특정 보안 공격을 피하고자 client_isn의 선택을 적절히 임의 추출
    • 2단계: TCP SYN 세그먼트를 포함하는 IP 데이터그램이 서버 호스트에 도착
      -> 서버는 데이터그램으로부터 TCP SYN 세그먼트 추출 -> TCP 버퍼와 변수 할당
      -> 클라이언트 TCP로 연결 승인 세그먼트를 송신
      • 이 연결 승인 세그먼트도 애플리케이션 계층 데이터를 포함X
      • 세그먼트 헤더 안에 3개의 중요한 정보를 포함한다.
        첫째, SYN 비트는 1로 설정
        둘째,TCP 세그먼트 헤더의 확인응답 필드는 client_isn+1로 설정
        셋째, 서버는 자신의 최초의 순서 번호(server_isn)를 선택하고,TCP 세그먼트 헤더의 순서 번호 필드에 이 값을 넣는다.
      • 이 연결 승인 세그먼트는 사실상, “나는 당신 의 최초 순서 번호 clientjsn을 가지고 연결을 시작하자는 당신의 SYN 패킷을 수신했다. 나는 이 연결 설정에 동의한다. 나 자신의 최초의 순서 번호는 server_isn이다”라고 말하는 것
      • 연결 승인 세그먼트는 때때로 SYNACK 세그먼트로 불린다.
    • 3단계: 연결 승인 세그먼트를 수신하면,클라이언트는 연결에 버퍼와 변수를 할당
      -> 클라이언트 호스트는 서버로 또 다른 세그먼트를 송신
      • 이 마지막 세그먼트가 서버의 연결 승인 세그먼트를 확인하는 것
        (확인응답 필드 안에 server_isn+1 값을 넣어서)
      • 연결이 설정되었기 때문에 SYN 비트는 0으로 설정
      • 여기서는 클라이언트에서 서버로의 데이터를 세그먼트 페이로드에서 운반 가능
    • 위 단계가 다 끝나면 서로 송수신 가능, 이 후부터 SYN 비트는 0으로 설정
    • = 세방향 핸드 셰이크

TCP 연결 끊기

  • 연결에 참여하는 두 프로세스 중 하나가 연결을 끝낼 수 있음
  • 연결이 끝날 때,호스트의 ‘자원’(버퍼와 변수)은 회수됨.
  • ex) 클라이언트가 연결 종료를 결정한다고 가정
    1. 클라이언트 TCP가 서버 프로세스에게 특별한 TCP 세그먼트(연결 종료 명령) 전송
      • ㄴ 세그먼트 헤더에 1로 설정된 FIN 비트라 불리는 플래그 비트를 포함
    2. 서버가 이 세그먼트를 수신하면,서버는 클라이언트에게 확인응답 세그먼트 전송
    3. 이후, 서버는 FIN 비트가 1로 설정된 자신의 종료 세그먼트 전송
    4. 클라이언트는 서버의 종료 세그먼트에 확인응답
      - 이 시점에서 두 호스트의 모든 자원은 할당이 해제됨.

TCP 상태 전이

  • TCP 연결 동안 각 호스트의 TCP 프로토콜은 다양한 TCP 상태를 두루 전이함.
  1. 클라이언트 TCP는 CLOSED 상태에서 시작
    -> 클라이언트측의 애플리케이션은 새로운 TCP 연결 시작
    • = 클라이언트의 TCP가 서버의 TCP에게 SYN 세그먼트를 송신
  2. SYN 세그먼트를 송신한 뒤,클라이언트 TCP는 SYN_SENT 상태로 들어감.
    • SYN_SENT 상태 동안, 클라이언트 TCP는 서버 TCP로부터 1로 설정된 SYN 비트와 클라이언트의 이전 세그먼트에 대한 확인응답을 가진 세그먼트를 기다림.
  3. SYN과 ACK를 수신하면,클라이언트 TCP는 ESTABLISHED 상태로 들어감.
    • TCP 클라이언트는(애플리케이션에서 발생된) 페이로드 데이터를 포함하는 TCP 세그먼트를 송,수신 가능
    • 클라이언트가 연결 종료를 희망한다고 가정하과 클라이언트 TCP가 1로 설정된 FIN 비트를 포함하는 TCP 세그먼트를 송신
  4. FIN_WAIT_1 상태로 들어감
    • 클라이언트 TCP는 서버로부터 확인응답을 포함하는 TCP 세그먼트를 기다림
  5. 이 ACK 세그먼트를 수신하면,클라이언트 TCP는 FIN_WAIT_2 상태로 들어감.
    • 클라이언트는 서버로부터 1로 설정된 FIN 비트를 포함하는 다른 세그먼트 기다림. 6. 이 FIN 수신하면 클라이언트는 ACK를 전송하고, TIME_WAIT 상태로 들어감.
    • 이는 TCP 클라이언트가 ACK가 손실되면 마지막 확인응답을 재송신함.
    • 여기서 소비되는 시간은 구현따라 다르지만 대체로 30초,1분 또는 2분
  6. 대기 시간이 끝나면 연결은 정식으로 종료되고,클라이언트 측의 (포트 번호를 포함한) 모든 자원이 해제된다.

  • 서버측 상태 전이는 알아서 봐라~

  • 만약 수신자에게 (없는 목적지 포트번호, 출발지 IP주소)의 TCP 세그먼트를 수신하면?
    • 그러면 수신자는 출발지로 특별한 리셋 세그먼트를 전송
      • 이 TCP 세그먼트는 1로 설정한 RST 플래그 비트를 가짐.
      • ㄴ= '그 세그먼트에 대한 소켓은 없으니까 세그먼트를 재전송하지 말라'
    • 만약 UDP 패킷이면 수신자는 5장의 논의처럼 특별한 ICMP 데이터그램을 전송
profile
인생 살자.

0개의 댓글

관련 채용 정보