관리 메뉴

너와 나의 스토리

[CH.3] Transport Layer - multiplexing/demultiplexing, Connectionless transport: UDP, principles of reliable data transfer 본문

Computer Networks/이론

[CH.3] Transport Layer - multiplexing/demultiplexing, Connectionless transport: UDP, principles of reliable data transfer

노는게제일좋아! 2019. 10. 7. 12:53
반응형

application processes는 서로 message를 운반하기 위해 transport layer에서 제공하는 logical communication을 이용한다.

 

 

Transport services and protocols

  • 다른 호스트에서 작동하는 app 프로세스들 사이에서 logical communication을 제공한다
  • end systems에서 transport protocols이 작동된다.
    • 보내는 측: 메시지를 segment 단위로 쪼개서 network layer에 보낸다
    • rcv 측: segments를 message로 재조합해서 app layer로 보낸다.
  • app에 사용 가능한 transport protocol -> TCP and UDP

 

 

Transport vs network layer

  • network layer(3계층): 호스트들 사이에서 logical communication
  • transport layer(4계층): 프로세스들 사이에서 logical communication
    • network layer services에 의존

 

 

Internet transport-layer protocols

  • transport layer protocols는 네트워크 라우터가 아닌 end system에서 구현된다. (host 내에서 작동)

  • reliable, 순서대로 전달 (TCP)
    • congestion control
    • flow control
    • connection setup
  • unreliable, 순서대로 전달 안됨(UDP)
    • no-frills extension of "best-effort" IP

 

 

 

 

 

 

 

IP

  • network layer protocol은 internet protocol을 줄여 IP라고 부른다.
  • IP 서비스 모델은 호스트들 간에 논리적 통신을 제공하는 best-effort delivery service이다.
    • 이것은 IP가 통신하는 호스트들 간에 세그먼트를 전달하기 위해 최대한 노력하지만, 어떤 보장도 하지 않는다는 것을 의미한다.
    • 특히, IP는 세그먼트가 전달되는지, 순서대로 전달되는지 그리고 데이터의 무결성을 보장하지 않는다.
    • 그렇기 때문에 IP를 비신뢰적인 서비스(unreliable service)라고 부른다.

 

 

Multiplexing/demultiplexing 공부 전 배경지식

  • Multiplexing/demultiplexing : "호스트-대-호스트 전달"을 "프로세스-대-프로세스 전달"로 확장하는 것
    • 호스트-대-호스트 전달: network layer (IP)
    • 프로세스-대-프로세스 전달: transport layer (TCP/UDP)
      • 실제로 데이터를 직접 프로세스로 전달하지 않고, 중간 매개자인 소켓에게 전달한다.
      • 호스트에 하나 이상의 소켓이 있을 수 있고, 식별자를 가진다.
  • TCP/UDP는 헤더에 오류 검출 필드를 포함함으로써 무결성 검사를 제공한다.
  • UDP가 제공하는 유일한 두 가지 서비스:
    • 프로세스 대 프로세스 데이터 전달
    • 오류 검출
  • TCP가 제공하는 서비스:
    • UDP가 제공하는 서비스 + reliable data transfer
    • 흐름 제어, 순서 번호, 확인 응답, 타이머를 사용함으로써 TCP는 송신하는 프로세스로부터 수신하는 프로세스에게 데이터가 순서대로 정확하게 전달되도록 한다. 
    • 이처럼 TCP는 end system 간에 IP의 비신뢰적인 서비스를 프로세스 사이의 신뢰적인 데이터 전송 서비스로 만들어 준다.
    • 또한 TCP는 혼잡 제어(congestion control)를 사용한다.
      • congestion control: 한 TCP 연결이 과도한 양의 트래픽으로 모든 통신하는 호스트들 사이의 스위치와 링크를 폭주되게 하는 것을 방지하는 것
      • TCP는 혼잡한 네트워크 링크에서 각 TCP 연결이 링크의 대역폭을 공평하게 공유하여 통과하도록 해준다.(송신할 때, TCP가 트래픽 조절)
      • UDP는 트래픽 조절되지 않음 -> 어떤 속도로도 전송 가능

 

 

Multiplexing/demultiplexing

  • 다중화와 역다중화는 모든 컴퓨터 네트워크에서 필요하다
  • transport layer은 실제로 데이터를 프로세스에 직접 전달하지 않는다. 대신에 중간 매개자인 소켓에게 전달한다.
    • 하나의 호스트에 소켓 여러 개가 있을 수 있으므로, 소켓은 유일한 식별자를 가진다.
  • 수신 측 호스트가 수신한 transport layer 세그먼트를 어떻게 적절한 소켓으로 향하게 하는지에 대해 생각해보자.
  • 수신 측의 transport layer은 수신 소켓을 식별하기 위해서 필드를 검사한다(세그먼트에 있는 필드 집합)
  • 그리고 이 세그먼트를 해당 소켓으로 보낸다.
  • transport layer 세그먼트의 데이터를 헤더 정보를 사용해서 올바른 소켓으로 전달하는 작업을 demultiplexing(역다중화)라고 한다.
  • 출발지 호스트에서 소켓으로부터 데이터를 모으고, 각 데이터에 헤더 정보(헤더 정보 추가)로 캡슐화해서 세그먼트를 생성하고, 그 세그먼트들을 network layer로 전달하는 작업을 multiplexing(다중화)라고 한다.

 

 

 

network layer에서 수신한 세그먼트를 위쪽의 프로세스 P1, P2로 demultiplexing 한다.

 

중간 호스트의 transport layer은 프로세스의 소켓으로부터 바깥으로 나가는 데이터를 모으고, 다음엔 transport layer 세그먼트들로 만들고, 이 세그먼트들을 아래 network layer로 전달한다.(multiplexing)

 

 

 

 

 

 

 

 

 

 

 

 

어떻게 demultiplexing이 작동될까?

  • transport layer 다중화에서 두 가지 요구 사항:
    1. 소켓은 유일한 식별자를 가진다.
    2. 각 세그먼트는 세그먼트가 전달될 적절한 소켓을 가리키는 특별한 필드를 가진다.
      • 특별한 필드: 출발지 포트 번호(source port number field)와 목적지 포트 번호 필드
      • 각각의 포트 번호는 0~65535까지 16비트 정수이다. 그중에서 0~1023까지의 포트 번호를 잘 알려진 포트 번호라고 하여 사용을 엄격하게 제한하고 있다. 
        • HTTP(포트 번호 80), FTP(포트 번호 21)처럼 이미 사용 중

  • UDP에서 기본적인 demultiplexing 동작 방식
    1. 호스트의 각 소켓은 포트 번호를 할당받는다.
      • who? os가 포트 번호 할당
      • how? list를 관리하면서 서로 다른 포트 번호를 할당
    2. 그리고 세그먼트가 호스트에 도착하면, transport layer은 세그먼트 안의 목적지 포트 번호를 검사하고 상응하는 소켓으로 세그먼트를 보내게 된다.
    3. 그러면 세그먼트의 데이터는 소켓을 통해 해당되는 프로세스로 전달된다. 
  • TCP의 다중화/역다중화는 좀 더 많은 의미를 갖고 있음

 

 

연결 지향 demux  -> TCP 역다중화

  • TCP 소켓과 UDP 소켓 사이의 다른 점은 TCP 소켓은 4가지 요소들의 집합: [출발지 IP 주소, 출발지 포트 번호, 목적지 IP주소, 목적지 포트 번호]에 의해서 식별된다는 것이다.
    • 목적지가 같아도 출발지가 다르면 다른 소켓으로 감
  • 서버 호스트는 동시에 존재하는 많은 TCP 소켓을 지원할 수 있다.

 

 

Connectionless transport: UDP

  • UDP는 다중화/역다중화 기능과 간단한 오류 검사 기능을 제외하면 IP에 아무것도 추가하지 않는다.
  • UDP를 사용하는 이유
    • UDP 송신자와 수신자 사이의 handshaking 없다 -> no connection establishment -> delay가 없다
    • 송수신자의 연결 상태가 없어 simple
    • 헤더 사이즈가 작다
    • congestion control이 없다 -> 원하는 만큼 빠를 수 있다.

 

Application Application layer protocol 하위 transport protocol 
전자메일 SMTP TCP
원격 터미널 접속 Telnet TCP
HTTP  TCP
파일 전송 FTP TCP
네트워크 관리 SNMP UDP
이름 변환 DNS UDP

 

 

UDP: Segment header

 

UDP 헤더는 2바이트씩 구성된 4개의 필드를 가진다.

 

 

 

 

 

 

 

 

 

 

UDP checksum

  • 목표: segment 전송 시 에러 탐지 (e.g. flipped bits)
    • 세그먼트가 출발지로부터 목적지로 이동했을 때, UDP 세그먼트 안의 비트에 대한 변경사항이 있는지 검사
  • 송신자:
    • 16bit 정수의 시퀀스로 헤더의 필드를 포함한 세그먼트의 콘텐츠를 다룬다.
    • checksum: 세그먼트 안에 있는 모든 16비트 워드 단위로 더하고 이에 대하여 다시 1의 보수를 수행하며, 덧셈 과정에서 발생하는 오버플로우는 "윤회식 자리올림(wrap around)"한다. 이 결과 값이 체크섬 필드에 삽입된다.
  • 수신자:
    • 받은 세그먼트의 체크섬을 계산한다.
    • 계산한 체크섬과 체크섬 필드의 값과 같은지 확인한다.
      • 다르면 에러 탐지한 것

 

checksum 구하는 법

  1. 값들을 다 더함 
  2. overflow 되면 1을 더함
  3. 1의 보수를 취함 (0<->1 바꾸기)

 

 

Principles of reliable data transfer

 

 

 

 

 

 

 

 

 

<- network layer

 

 

TCP는 비신뢰적인 종단 간의 네트워크 계층(IP)의 바로 상위에 구현된 신뢰적인 데이터 전송 프로토콜이다.

 

 

 

 

왜 하위 채널에서 데이터 받을 때는 rdt일까?

 

하위 채널에서 패킷 받아올 때, tcp가 resemble하는 과정을 거치는데, 이 과정에서 rdt가 가능해진다고 생각됨.

 

 

 

 

 

 

 

 

rdt1.0: 완벽하게 신뢰적인 채널 상에서의 신뢰적인 데이터 전송

  • no bit errors
  • no loss of packets 

를 가정하자 => 완벽해서 피드백할 필요가 없음

상위 계층의 호출 기다림

rdt_send(data): 상위 계층에서 데이터 받음

packet =make_pkt(data): 데이터를 포함한 패킷 생성

udt_send(packet): 패킷 보냄

 

 

하위 계층의 호출 기다림

rdt_rcv(packet): 하위 채널로부터 패킷 수신

extract(packet, data): 패킷으로부터 데이터 추출한 후 

deliver_data(data): 상위 계층으로 데이터 전달 

 

 

 

rdt2.0: 비트 오류가 있는 채널 상에서의 reliable data transfer 

  • 패킷 안의 비트가 flip 될 수 있으므로 chkecsum이 필요
  • 어떻게 에러 복구할까?
    • acknowledgements(ACKs): 수신자가 송신자한테 명시적으로 패킷(pkt)을 잘 받았다고 말한다.
    • negative acknowledgement(NAKs): 수신자가 송신자한테 pkt에 에러 있다고 말한다.
  • rdt2.0: rdt1.0에서 추가된 점
    • 에러 탐지
    • 수신자가 송신자한테 컨트롤 메시지(ACK, NAK)를 보내서 피드백

 

 

 

sender => stop-and-wait

∧: do nothing

 

 

 

 

 

 

 

 

 

 

 

 

rdr2.0에는 치명적인 결점이 있다.

  • 송신자가 손상된 ACK/NAK를 수신할 때 현재 데이터 패킷을 다시 송신하면 수신자는 중복된 패킷을 얻게 된다.
  • 여기서 문제: 마지막으로 전송된 ACK/NAK이 송신자에게 정확하게 수신되었는지 알 수 없다.
  • 해결책: 데이터 패킷에 새로운 필드를 추가하고 이 필드 안에 순서 번호(sequence number)를 삽입하는 방식으로 데이터 패킷에 송신자가 번호를 붙으는 것
  • 수신자는 수신된 패킷이 재전송인지 확인할 때는 이 순서 번호만 확인하면 된다.

 

rdt2.1: 깨진(잘못된) ACK/NAKs 처리 

  • 송신자:
    • 패킷에 순서(seq) 추가
    • seq는 0,1이면 충분
      • 어차피 하나 보내 놓고 ACK/NAK 패킷 올 때까지 기다리는 stop-and-wait 구조이니까
  •  수신자:
    • 반드시 패킷이 중복되었는지 확인해야 한다.
    • 원하는 패킷을 0 또는 1로 나타냄
    • 수신자는 최근에 보낸 ACK/NAK을 송신자가 잘 받았는지 알 수 없다

receiver에서 빨간 상자 부분을 보자.

하위 계층으로부터 1을 기다리다가 0을 받았는데, 별다른 이상이 없었다면, NAK을 보내는 것이 아니라 이미 전에 수신한 패킷에 대한 ACK을 전송한다. 

예를 들어, 송신자가 1,2를 보내고 수신자는 1,2에 대한 ACK을 이미 한 상태에서 수신자가 4를 받으면 2에 대한 ACK을 다시 보낸다.

 

 

rdt2.2: 비트 오류를 갖는 채널을 위한 NAK 없는 신뢰적인 데이터 전송 프로토콜

  • 오로지 ACK만 사용한다.
  • 수신자가 확인 응답하는 패킷의 순서 번호를 반드시 포함해서 ACK을 보내야 한다.
  • 송신자가 중복된 ACK을 수신하면(같은 패킷에 대한 ACK을 두 번 받으면) 송신자는 수신자가 이 패킷의 다음 패킷을 제대로 받지 못했음을 알게 된다. => 재전송

 

 

rdt3.0: 에러와 손실이 있는 채널에서 rdt

  • 새로운 가정: 채널은 패킷을 손실할 수도 있다.
  • 'ACK, Seq num, ACK, 재전송'으로 충분하지 않다.
  • 접근: 송신자가 ACK을 기다리는 시간을 통제할 타이머를 설정
    • 일정 시간이 지나도 ACK이 안 오면 재전송
    • 만약 패킷이 손실된 게 아니라 그냥 지연된 건데 time out이 된 경우 수신자는 패킷을 중복해서 받게 된다.
    • 수신자는 ACK 할 때, 패킷의 seq num을 지정해서 보내야 한다.

왼쪽 위 동그라미부터 시계방향으로 차근차근 봐보자

 

0. 상위 계층으로부터 0번 호출을 기다림

1.

  • event:
    • rdt_rcv(rcvpkt): ACK/NAK 패킷을 받음
  • action:
    • 아무것도 안 함

2. 

  • event:
    • rdt_send(data): 상위 계층에서 데이터를 보내옴 (상위 계층인 application layer은 reliable transfer)
  • action:
    • sndpkt = make_pkt(0,data,checksum): seq num, 데이터, 체크섬을 넣어서 패킷을 만듦
    • udt_send(sndpk): 수신자한테 패킷을 전송 (unreliable transfer)
    • start_timer: 타이머 시작

 

3. ACK0을 기다림

4.

  • event:
    • rdt_rcv(rcvpkt): 하위 채널로부터 패킷(ACK/NAK 패킷)을 수신 
    • corrupt(rcvpkt): 받아온 패킷에 이상 있음
    • isACK(rcvpkt,1): 0번을 보냈는데 1에 대한 ACK이 옴
  • action:
    • 아무것도 안 함 -> 타이머 시간 지나도 제대로 안 오면 그때 처리

5.

  • event:
    • timeout: 타이머 시간이 지났어요~
  • action:
    • udt_send(sndpkt): 패킷 재전송
    • start_timer: 타이머 다시 시작

6. 

  • event:
    • rdt_rcv(rcvpkt): ACK/NAK 패킷을 받음
    • notcorrupt(rcvpkt): ACK/NAK 패킷에 이상 없음
    • isACK(rcvpkt,0): 0번 ACK이 옴
  • action:
    • stop_timer: 타이머 멈춤

7. 상위 계층으로부터 1번 호출을 기다림

8.

  • event:
    • rdt_rcv(rcvpkt): ACK/NAK 패킷을 받음
  • action:
    • 아무것도 안 함

9. 

  • event:
    • rdt_send(data): 상위 계층에서 데이터를 보내옴 (상위 계층인 application layer은 reliable transfer)
  • action:
    • sndpkt = make_pkt(1,data,checksum): seq num, 데이터, 체크섬을 넣어서 패킷을 만듦
    • udt_send(sndpk): 수신자한테 패킷을 전송 (unreliable transfer)
    • start_timer: 타이머 시작

10. ACK1을 기다림

뒤는 위와 동일

 

 

rdt3.0 in action

 

 

 

Performance of rdt3.0

  • rdt3.0은 올바르게 작동되기는 하나, 효율적이지 못하다  
  • 링크 전송률(R)이 1 Gbps, 전파가 15 ms, 패킷 길이가 8000 bit일 때, 파일을 전송하는데 걸리는 시간은 다음과 같다.

  • $U_{sender}$: (전체 걸린 시간) 분에 (실제 보내는 데 사용한 시간)

  • 이유: stop-and-wait 프로토콜 때문이다

 

 

 

Pipelined protocols

  • pipelining: 확인 응답(ACK/NAK) 기다리지 않고 여러개의 패킷을 전송
  • stop-and-wait과 달리 확인 응답 받기 않은 패킷을 여러 개 전송하기 때문에 seq num의 범위가 증가해야 한다.
  • 송신자와 수신자가 버퍼링을 한다. 

  • 파이프 라인 오류 회복의 두 가지 기본적인 접근 방법:
    • go-Back-N: N부터 반복
    • selective repeat: 선택적 반복
  • Utilization 증가

  • Go-back-N:
    • 송신자는
      • 확인 응답을 기다리지 않고 여러 패킷을 전송할 수 있지만, 파이프라인에서 확인 안된 패킷이 N개가 넘으면 안된다.
      • 아직 ack되지 않은 패킷 중 가장 오래된 것에 대한 타이머를 가지고 있다.
        • time out되면 ack이 오지 않은 패킷들을 전부 재전송한다.

send_base: 확인 응답이 안 된 가장 오래된 패킷의 순서 번호

nextseqnum: 사용되지 않은 가장 작은 순서 번호

 

[0,send_base-1]: 송신 했고, ack도 다 받은 패킷들

[send_base, nextseqnum-1]: 송신 했고, ack을 아직 못 받은 패킷들

[nextseqnum,base+N-1]: 데이터 도착하면 바로 전송 가능한 부분

 

 

  • 수신자는
    • 오로지 축적된 ack(cumulative ACK)만을 보낸다.
      • 순서가 올바르게 제대로 도착한 가장 최근 패킷의 seq num과 함께 ack을 보낸다. 
      • 중복된 ACK을 보낼 수도 있다
      • 받고자하는 패킷의 번호(expectedseqnum)만 기억하면 된다.
    • 순서가 잘못된 패킷을 받으면 ex) 1,2,5 이렇게 받으면
      • 버퍼링하는게 아니라 그냥 버림
      • 순서 제대로 온, 전에 ack한 패킷 다시 ack 보냄

GBN in action

 

 

  • Selective repeat
    • : 송신자가 전송한 패킷 중에 오류가 발생했을 것 같다고 의심되는 패킷만을 다시 전송
      • 불필요한 재전송 피함
    • 필요에 따라 각각의 개별적인 재전송은 수신자가 올바르게 수신된 패킷에 대한 개별적인 확인 응답을 요구할 것.
      • 패킷을 버퍼하여 상위 계층에 순서대로 전달
    • 송신자는 ACK를 못 받은 패킷만 재전송
      • 패킷(ACK 못 받은)마다 타이머가 있음
    • sending window
      • GBN이랑 똑같

  • 송신자
    • 상위 계층에서 데이터가 들어오면
      • window에 넣을 수 있으면 패킷 송신
    • timeout(n)
      • n번 패킷 다시 보내고, 타이머 다시 시작
    • ACK(n) in [sendbase,sendbase+N]
      • ack 받은 걸로 표시
      • 만약 ack 받은 것이 원래 가장 작은 번호의 unACKed 패킷이였으면 send_base가 다음 unACKed 패킷 가리키는 곳으로 이동
  • 수신자
    • [rcvbase,rcvbase+N-1] 내의 n번 패킷 수신
      • ACK(n) 보냄
      • 순서 다르면 -> 버퍼링
      • 순서 맞으면 상위 계층으로 전송(버퍼에 이거 넣어서 순서 맞으면 순서 맞는 것들 다), window 이동
    • [rcvbase-N,rcvbase-1] 내의 n번 패킷 수신
      • ACK(n)
    • otherwise:
      • 무시

 

 

Selective repeat in action 

 

Seletive repeat: dilemma

 

문제: 다섯 번째 패킷의 원래 전송과 첫 번째 패킷의 재전송을 구별할 수 있는 방법이 없다.

 

 

 

결론: window의 크기는 SR 프로토콜에 대한 순서번호 공간 크기의 절반보다 작거나 같아야 한다.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

출처: [Computer networking: A top-down approach, 6th]

반응형
Comments