이 글은 2018년 2학기 아주대학교 Paul Rajib 교수님의 Computer Network 수업을 듣고 작성한 수업노트입니다. 부족한 내용이나 오류가 있을 수 있습니다.
UDP
UDP(User Datagram Protocol)는 트랜스포트 레이어에서 포트 번호를 이용해서 어플리케이션 레이어에서 전송된 데이터를 멀티플렉싱해 세그먼트로 만들어 네트워크 레이어로 보내고, 반대로 네트워크 레이어에서 올라온 패킷을 디멀티플렉싱해 어플리케이션레이어로 보낸다.
UDP 세그먼트는 다음과 같은 특징을 가진다
- 내용이 전송 중에 손실될 수 있다.
- 전송되는 세그먼트의 순서가 바뀔 수 있다.
- Connectionless: 연결 상태를 만들지 않는다.
- 오버해드가 적다: 세그먼트에 추가되는 헤더가 적다.
- 빠르다: UDP가 자체적으로 쓰루풋을 줄이지 않고, 세그먼트를 원하는 만큼 보낼 수 있다.
UDP 헤더는 2바이트 헤더 4개 총 8바이트로 구성되어있다. 송신포트번호, 목적지 포트번호, 데이터의 길이, 데이터의 체크섬값으로 나누어져있다.
Checksum
체크섬은 전송된 데이터가 변형이 되지 않았는지 확인하는 값이다. 전송하려는 세그먼트의 값들을 이용해 체크섬을 만들어서 세그먼트에 담아 전송한다. 세그먼트를 받은 상대는 세그먼트의 값들을 이용해 다시 체크섬을 계산하고 세그먼트에 저장된 체크섬 값과 비교한다. 세그먼트의 값들 중 하나라도 변경되면 체크섬 값이 바뀌기 때문에 이 두 값이 다르다면 전송 중 세그먼트의 내용이 변형되었음을 의미한다.
UDP 체크섬을 계산하는 방법은 간단하다. UDP 세그먼트의 도착 IP주소, 송신 포트번호, 입력 포트번호, 데이터 길이, 그리고 UDP 데이터들을 16비트단위로 쪼개서 전부 더한다. 그리고 오버플로되서 캐리된 값들을 다시 더하고 1의 보수를 취한다. 이렇게해서 나온 값을 체크섬 값으로 사용한다. 체크섬 필드는 체크섬 계산할 때는 0으로 가정한다.또 네트워크 레이어의 IP관련 필드들도 계산에 이용한다.
모든 값을 더하기 때문에 하나라도 값이 바뀌면 체크썸도 바뀐다. 단 전송 중 체크썸 값이 변형되거나, 데이터가 변형됬는데 체크섬 값이 동일할 경우 확인할 수 없다. 물론 그럴 확률은 매우 적을 것이다.
UDP Reliable Data Transfer
체크썸을 이용하면 데이터가 변형없이 정확하게 도착했단 걸 알 수는 있지만, 데이터가 순서대로 왔는지, 혹은 중간에 사라지진 않았는지 알 수는 없다. 이런 문제를 해결하기 위해서 Application Layer에서 몇가지 기법들을 적용할 수 있다.
ARQ
ARQ(Automatic Repeat reQuest)는 전송 중 세그먼트가 손실되면 자동으로 세그먼트를 재전송해서 데이터가 손실되는 일을 막는다. 또 한 세그먼트가 전송이 되지 않으면 이후의 세그먼트를 보내지 않기 때문에 순서가 뒤바뀌어서 전달될 일이 없다.
송신자가 세그먼트를 전송할 때 세그먼트마다 Sequence Number라고 불리는 번호를 부여한다. 이 번호는 새로 세그먼트를 보낼 때마다 증가한다. 수신자가 세그먼트를 받을 경우 ACK(Acknowledgement)라 불리는 수신성공 세그먼트에 시퀀스 번호를 담아서 돌려줘하며, 송신자는 이 ACK를 받아야만 다음 세그먼트를 전송한다. 만약 내용물이 변경되었다면 NCK(Not Acknowledged)와 해당 세그먼트의 시퀀스 번호를 보내서 송신자에게 다시 그 세그먼트를 전송하도록 한다.
하지만 세그먼트가 손실되서 전달되지 않으면 ACK도, NCK도 받을 수 없다. 그렇기 때문에 세그먼트를 전송할 때 타이머를 걸어서 전송 후 일정 시간이 지나도 아무 응답이 없을 경우 세그먼트를 다시 전송하는데 이것이 타임아웃(Timeout) 매커니즘이다. 이 타임아웃 매커니즘에서 얼마나 기다릴지를 정하는 방식이 있는데 이는 다른 글에서 서술하겠다.
이 ARQ 방식의 단점은 느리다는 것이다. UDP 세그먼트는 크기가 고정되어있기 때문에 한번에 많은 양을 보내지 못한다. 이를 보완하는 방식들이 몇가지 존재한다.
GBN ARQ
GBN ARQ는 한번에 여러 세그먼트를 전송하고 그 세그먼트들을 기다리는 방식이다. 이런 방식을 파이프라인 방식(Pipeline Protocol)이라고 한다. ACK를 받지 않아도 여러 세그먼트를 전송하고 ACK를 받을 때마다 이후의 세그먼트를 하나씩 더 전송하게 된다.한번에 전송 가능한 세그먼트의 범위를 윈도우라고한다.
위 예시에서는 처음에 패킷을 3개를 순서대로 전송한다. 이후에 ACK0이 오면 하나가 전송이 제대로 됬다고 판단하고 전송자는 window를 한 칸 옆으로 옮겨서 7번째 패킷도 전송범위에 포함시킨다. 이 때 수신자는 자신의 받은 패킷의 시퀀스 번호와 다음에 예상되는 시퀀스 번호도 함께 돌려준다.
만약 패킷이 변형되거나, 손실되서 공백(Gap)이 발생할 수 있다. 변형될 경우 NCK를 보내지 않으며 공백이 발생한 경우 그 세그먼트는 버려진다. 1, 2 받고 4를 받은 경우 4세그먼트는 버려지며 ACK2를 보낸다. 이럴 경우 송신자는 3번 세그먼트부터 다시 전송을 해야한다.
GBN ARQ는 모든 세그먼트마다 타이머를 설정하고 타임아웃을 계산하지 않고 가장 예전에 보낸 세그먼트에 대해서만 타이머를 설정한다. 1 세그먼트에 타이머가 설정되어있는데 ACK3이 응답되면 3세그먼트까지 모두 받았다는 의미기 때문에 해당 타이머를 없애고 이후에 ACK를 받지 못한 가장 오래된 세그먼트에 다시 타이머를 설정한다.
만약 타임아웃이 발생하거나 NCK가 응답되면 송신자는 현재 윈도우 범위에 있는 모든 세그먼트를 다시 전송한다. 예를 들어 세그먼트 1, 2, 3, 4를 전송했을 때 1, 3, 4번 패킷은 제대로 전송됬지만 2번 패킷은 손실됬다고 하면, 수신자는 ACK1을 보내고 3, 4는 버린다. 송신자는 ACK1을 받은 후 윈도우 범위를 2, 3, 4, 5로 이동하고 기다리다가 2번 세그먼트에서 타임아웃이 발생한다. 그러면 세그먼트 2, 3, 4, 5를 다시 전송하는데 이러면 2, 3, 4 세그먼트는 2번 전송되게 된다. 이런 이유로 GBN ARQ의 윈도우 범위가 지나치게 크다면 네트워크 문제가 발생할 때마다 대량의 패킷을 다시 보내게 된다.
SR ARQ
SR ART(Selective-Repeat ARQ)는 GBN ARQ의 이런 단점을 보완하기위해 고안됐다. 윈도우의 모든 세그먼트들에 타이머를 달고 ACK를 받지 않아 타임아웃이 발생하는 세그먼트만 전송한다. 수신자도 순서를 벗어난 세그먼트도 윈도우 범위 내라면 받아들여서 저장하고, 받은 세그먼트에 해당하는 ACK를 돌려준다.
그렇다보니 SR ARQ에선 ACK3을 받아도 3번 세그먼트까지 다 받았다는 의미가 아니라, 3번 세그먼트를 받았다는 의미가된다.
Sequence Number Issue
ARQ에서 사용하는 시퀀스 번호는 무한대까지 증가할 수 없고 한계가 존재한다. 만약 시퀀스 번호를 2비트로 표현한다면 0, 1, 2, 3, 이후에 다시 0이 된다. 이 경우 아래와 같은 문제가 발생할 수 있다.
위 예시를 보면 수신자가 날리는 ACK가 전부 손실됬다. 송신자는 타임아웃이 발생하면 0번 세그먼트부터 보내는데, 이 경우 수신자는 이미 윈도우를 옆으로 옮겨서 새로운 0번 세그먼트의 위치에 데이터를 저장하려고한다. 하지만 송신자는 세그먼트는 4세그먼트가 아니라 0세그먼트를 전송하려고 하고, 데이터가 밀려서 저장되게된다.
이런 문제를 방지하기위해서는 윈도우의 크기가 항상 시퀀스 번호의 최대값의 절반 이하여야한다.