2024. 4. 19. 18:00ㆍComputer Science/Networking
Reliable Data Transfer Protocol (rdt)
- 패킷 로스가 나는 상황이나 순서대로 패킷이 들어오지 않는 등, 네트워크 상의 Channel들은 대부분 신뢰도가 떨어지는(Unreliable) 경우가 많다. 이때 이러한 Channel상에서 Reliable한 Data Transfer를 해보자! 는게 rdt 프로토콜이다.
rdt 1.0 : 신뢰 가능한 채널에서 신뢰성 있는 전송
- 기본적으로 (외계인이 만든 하이테크놀로지던 간에) 신뢰 가능한 채널이 있다고 가정하므로, rdt 1.0의 구조는 단순하다.
- Sender는 데이터가 들어오면 패킷으로 만들어서 보내고, 리시버는 들어오면 뽑아서 message를 프로세스에 보낸다.
- 근데 문제는 현실에서 이럴리가 없으므로...
rdt 2.0 : 비트 에러가 발생할 수 있는 채널에서의 신뢰성 있는 전송
구조가 조금 복잡해졌다. 일단 ACK와 NAK라는 게 생겼다.
- ACK 는 "나 패킷 잘 받았어요, 감사합니다!" 라고 Receiver가 Sender에게 보내는 일종의 모시깽이(???)다.
- NAK 는 반면 "저 패킷을 이상해요!"라고 Receiver가 Sender에게 보내는 것이다. (에러를 어떻게 잡아내는지 궁금하다면 구글에 Checksum등을 검색해 보시라.)
- 어쨋든 rdt 2.0 하에서 Sender는 이제 패킷을 보내고 나서, ACK가 오기 까지 기다리게 된다. ACK가 왔으면 다음 패킷을 보내고, NAK가 왔으면 패킷을 다시 재전송 하게 된다. (Stop and Wait)
그런데 rdt 2.0에는 치명적인 문제가 있으니...
-> 만약 ACK/NAK에 에러가 생기면 어쩔 것인가? Sender는 Receiver에 무슨 일이 생긴지 모르게 되는데, 재전송 하면 중복의 우려가 발생한다. (예: 정상적으로 받았으나 ACK가 유실됬고, Sender가 상태를 몰라 한번 더 보낸다면 Reveicer는 두개의 패킷을 받게됨)
-> 그리고 이에 대한 해결책으로 천재 공돌이 너드들은 패킷에 Sequence를 붙이는 방법을 생각해낸다.
rdt 2.1 : 비트 에러(+ACK/NAK Corrupted)가 발생할 수 있는 채널에서의 신뢰성 있는 전송
도식화 한 구조가 매우 이해하기 어려우니, 예를 들어서 설명해보자. (* rdt2.1의 경우 Status가 0/1뿐이다 )
- Sender는 패킷0, 패킷1을 보내려고 한다. 먼저 패킷 0를 보내고, ACK/NAK0가 오기를 기다린다.
- Receiver는 패킷0를 수신한다. 이때 에러가 있으면 NAK0를 보내고, 아니면 ACK를 보낸다. 단, 괴상하게 패킷1이 왔으면(= 에러가 났으면) 일단 ACK를 보내고 패킷0을 다시 기다린다. (그러면 ACK를 받은 Sender가 State를 바꾸고 패킷 0를 보낼 것임)
- Sender는 이제 패킷 1을 보내고, ACK/NAK1이 오기를 기다린다.
- Receiver는 패킷1을 수신한다. 이때 에러가 있으면 NAK1를 보내고, 아니면 ACK를 보낸다. 단, 괴상하게 패킷0가 왔으면(=에러가 났으면) 일단 ACK를 보내고 패킷 1을 다시 기다린다. (그러면 ACK를 받은 Sender가 State를 바꾸고 패킷 1를 보낼 것임)
그러나 rdt 2.0에도 함정이 있으니...
>시퀸스 넘버가 충분하지 않다.
>Receiver에서 ACK/NAK가 잘 넘어가는지 어떻게 아는가?
그래서 또다시 공돌이들은 기가 막힌 방법을 생각해 냈으니..
rdt 2.2 : 비트 에러가 발생할 수 있는 채널에서의 신뢰성 있는 전송 ( 근데 ACK* 만 쓰는 )
도식화 한 구조가 매우 이해하기 어려우니, 예를 들어서 설명해보자.
> 먼저 Sender의 경우 패킷 0를 보내고, ACK0을 기다린다. 이때 만약 ACK1을 받았으면 패킷0을 재전송 한다.
> Receiver의 경우 패킷 0를 받는다. 이때 만약 시퀸스가 일치하지 않으면(패킷 0이 와야하는데 1이 옴, 또는 Corrupted) ACK1을 보낸다.
> (패킷 1 버전으로 반복...)
예를 들어서도 이해가 잘 안될 수 있는데, ACK에 에러가 나는 상황을 생각하면 편하다. (애초에 rdt2.0, 2.1은 패킷 에러를 상정한다! 유실이 아니다!) 저 위에서는, 만약 패킷0을 받고 ACK0을 보내다가 ACK0가 엉망진창이 되서 ACK1이 됬다고 해보자. (Bit Flip, Error, Etc...) 그러면 Sender는 다시 ACK0을 보낼 것이니, 이제 어느정도 이해가 될 것이라 믿는다.
그러나 이는 패킷 로스(Packe Queuing and Loss에 관해 검색해 보라.)가 발생하면 어떻게 할 수도 없으니, 우리의 공돌이들은 또 머리를 싸매 기가 막힌 방법을 찾아낸다.
rdt 3.0 : 비트 에러와 패킷 로스가 발생할 수 있는 채널에서의 신뢰성 있는 전송
한마디로, 로스가 나는 경우를 대비해 Sender가 일정 시간내에 ACK가 안오면 재전송 하는 방식이다. Receiver에서 설령 중복이 난다 하더라도, 무시하면 된다. 아래 예시를 참고해 보자.
> (B) 상황의 경우, 패킷 1이 전송되다가 유실 되었고 timeout(시간 초과)가 발생하여 Sender가 재전송 했다.
> (C) 상황의 경우, ACK1이 전송되다가 유실되었고 timeout이 떠서 Sender가 패킷 1을 재전송 했다. 따라서 Receiver는 패킷 1을 중복으로 받았는데, 이때 하나를 버리면 완벽해진다.
> (D) 상황의 경우, 네트워크 상황 때문에 ACK1의 전송이 늦어졌고 timeout이 떠서 Sender가 재전송 했다. 따라서 Receiver는 패킷 1을 중복으로 받았는데, 이때 하나를 버리면 완벽해진다.
이 얼마나 아름다운 방식인가? 근데 문제는, timeout interval은 어떻게 구해야 할까?
Timeout in TCP : using EWMA
유사 rdt 3.0을 사용하는 (fast retrasmission) TCP의 경우는, Timeout interval을 위와 같이 설정한다. 이때 EstimatedRTT와 DevRTT의 weight은 놀랍게도 경험적으로(...) 대게 사용한다. 정말이다, 교수님께 처음 들었을 때도 놀랐었다.
* 혹시나 위 내용에 오류가 있는 경우, 덧글 남겨주시면 바로 정정하도록 하겠습니다.
'Computer Science > Networking' 카테고리의 다른 글
Control Plane - OSPF, BGP (0) | 2024.05.30 |
---|---|
Control Plane - Routing Protocols (0) | 2024.05.30 |
Data Plane - NAT, DHCP (0) | 2024.05.30 |
Data Plane - IP Datagram, Subnets (0) | 2024.05.29 |
Data Plane - Router Architecture (0) | 2024.05.28 |