network - transport layer(2)

2020. 2. 12. 09:50Security/네트워크

* 신뢰적인 data transfer

sender

- rdt_send()가 이벤트로 발생.(하위 rdt에 data를 전달하기 위해 app가 호출)

- udt_send()가 액션으로 발생.(비신뢰적인 하위 채널에 data를 전달하기 위해 rdt가 호출)

- rdt는 신뢰적인, udt는 비신뢰적인 이라는 의미

 

receiver

- rdt_rcv()가 이벤트로 발생.(상위 rdt에 data를 전달하기 위해 호출) 발생

- deliver_data()가 액션으로 발생(rdt가 상위 layer에 data를 전달하기 위해 호출)

 

* FSM(finite-state machine)

 

state

- 어떠한 상태를 의미

- sender는 application에게 data를 받으려고, receiver는 ip에게 packet을 받으려고 대기하는 상태  

 

event

- 의도되지 않은 일이 발생

 

action

- 의도적으로 직접 하는 일

- atcion은 순서가 존재. 

 

* rdt 1.0(신뢰적인 채널에서 rdt)

- 하위 채널이 완전히 신뢰적인 경우

- no bit error(전송중 깨짐 방지), no loss of packets(전송중 손실 방지) 모두 보장

- data를 깨졌는지 확인하거나 할 필요가 없음

 

rdt 1.0의 fdm

sender

- wait for call from above(statement) : 상위계층(above)에서 data를 받는 것을 기다리는 상태

- rdt_send(data)(event) : application계층으로부터 data를 받음.

- packet = make_pkt(data)(action) : data를 packet으로 만듦.

- udt_send(packet)(action) : ip계층으로 packet을 보냄. sender는 다시 wait for call from above 상태로 돌아감

 

receiver

- wait for call from below(statement) : 하위계층(below)에서 data를 받는 것을 기다리는 상태.

- rdt_rcv(packet)(event) : ip계층으로부터 packet을 받음 

- extract(packet, data)(action) : packet에서 data를 추출

- deliver_data(data)(action) : data를 application 계층으로 보냄. receiver는 다시 wait for call from below 상태로 돌아감

 

* rdt 2.0(비트 오류가 있는 채널)

- bit error 가능성 존재(checksum을 통해 bit error감지)

- packet의 손실이나 순서는 보장 됨

- ack가 올때까지 보낸 packet을 보관해야 함

- stop and waitng 방식

- 만약 sender는 receiver의 ack가 오지 않는다면  NAK로 가정하고 packet 재전송해서 packet이 중복 될 수도 있음

 

수신측의 feedback
- acknowledgement(ACKs) : receiver가 sender에게 packet를 잘 받았다는 응답
- negative acknowledgement (NAKs) : receiver가 sender에게 packet이 error 또는 장애가 있다고 응답
- sender는 NAK인 경우 packet을 재전송


rdt 2.0에 부가적으로 필요한 protocol(rdt 1.0에 비해서)
- error 검출
- receiver feedback : 제어 msg (ACK,NAK)
- 재전송

 

rdt 2.0의 FDM

 

sender

- wait for call from above(statement) : 상위계층(above)에서 data를 받는 것을 기다리는 상태

- rdt_send(data)(event) : application계층으로부터 data를 받음.

- sndpkt = make_pkt(data, checksum)(action) : data를 checksum을 포함한 packet으로 만듦

- udt_send(sndpkt)(action) : ip계층으로 packet을 보냄

- wait for ack or nak(statement) : ack나 nak를 기다리는 상태

- rdt_rcv(rcvpkt) && isNAK(rcvpkt)(event) : receiver에게 받은 packet이 NAK임을 확인

- udt_send(sndpkt)(action) : ip계층으로 packet을 다시 보냄

- rdt_rcv(rcvpkt) && isACK(rcvpkt)(event) : receiver에게 받은 packet이 ACK임을 확인. sender는 다시 wait for call from above 상태로 돌아감

 

receiver

- wait for call from below(statement) : 하위계층(below)에서 packet을 기다리는 상태

- rdt_rcv(packet) && corrupt(rcvpkt)(event) : ip계층으로부터 받은 packet이 checksum으로 확인 결과 손상 

- udt_send(NAK)(action) : sender에게 받은 패킷이 NAK라고 전송

- rdt_rcv(packet) && notcorrupt(rcvpkt)(event) : ip계층으로부터 받은 packet이 checksum으로 확인 결과 정상 

- extract(packet, data)(action) : packet에서 data를 추출

- deliver_data(data)(action) : data를 application 계층으로 보냄

- udt_send(ACK)(event) : sender에게 받은 패킷이 ACK라고 전송

 

* rdt 2.1(ACK/NAK가 훼손되는 경우)

- sender는 receiver의 response가 올때까지 대기.

- sender는 receiver쪽의 상황을 알 수 없기때문에 항상 NAK로 가정하고 packet 재전송

- receiver가 재전송으로 인해 packet이 중복되는 현상을 해결

- 중복을 제어하기 위해 sender는 packet에 sequence number 추가

- receiver는 중복돤 packet을 버린다.

 

sender

- wait for call 0 from above(statement) : 상위계층(above)에서 squence number가 0인 packet으로 만들 data를 받는 것을 기다리는 상태

- rdt_send(data)(event) : application계층으로부터 data를 받음.

- sndpkt = make_pkt(0, data, checksum)(action) : data를 squence number가 0, checksum을 포함한 packet으로 만듦

- udt_send(sndpkt)(action) : ip계층으로 packet을 보냄

- wait for ACK or NAK(statement) : ack나 nak를 기다리는 상태

- rdt_rcv(rcvpkt) && {isNAK(rcvpkt) || corrupt(rcvpkt)} (event) : receiver에게 받은 packet이 NAK. 또는 receiver에게 받은 packet이 응답 자체가 깨져있음.

- udt_send(sndpkt)(action) : ip계층으로 packet을 다시 보냄

- rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isACK(rcvpkt)(event) : receiver에게 받은 packet이 손상되지 않음. 그리고 receiver에게 받은 packet ACK임을 확인. sender는 wait for call 1 from above 상태로 바뀜.

 

- wait for call 1 from above(statement) : 상위계층(above)에서 squence number가 1인 packet으로 만들 data를 받는 것을 기다리는 상태

- rdt_send(data)(event) : application계층으로부터 data를 받음.

- sndpkt = make_pkt(1, data, checksum)(action) : data를 squence number가 1, checksum을 포함한 packet으로 만듦

- udt_send(sndpkt)(action) : ip계층으로 packet을 보냄

- wait for ack or nak (statement) : ack나 nak를 기다리는 상태

- rdt_rcv(rcvpkt) && {isNAK(rcvpkt) || corrupt(rcvpkt)}(event) : receiver에게 받은 packet이 NAK. 또는 receiver에게 받은 packet이 응답 자체가 깨져있음.

- udt_send(sndpkt)(action) : ip계층으로 packet을 다시 보냄

- rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isACK(rcvpkt)(event) : receiver에게 받은 packet이 손상되지 않음. 그리고 receiver에게 받은 packet이 ACK임을 확인. sender는 wait for call 1 from above 상태로 바뀜.

 

receiver

- wait for call 0 from below(statement) : 하위계층(below)에서 sequence number가 0인 packet을 기다리는 상태

- rdt_rcv(packet) && notcorrupt(rcvpkt) && has_seq0(rcvpkt)(event) : ip계층으로부터 받은 packet이 checksum으로 확인 결과 정상. 그리고 packet의 sequence number가 0임을 확인

- extract(packet, data)(action) : packet에서 data를 추출

- deliver_data(data)(action) : data를 application 계층으로 보냄

- sndpkt = make_pkt(ACK, checksum) : ACK상태, checksum을 포함한 packet 생성.

- udt_send(sndpkt)(action) : sender에게 sndpkt 전송. receiver는 wait for call 1 from above 상태로 바뀜.

 

- wait for call 1 from below(statement) : 하위계층(below)에서 squence number가 1인 packet을 기다리는 상태

- rdt_rcv(packet) && notcorrupt(rcvpkt) && has_seq1(rcvpkt)(event) : ip계층으로부터 받은 packet이 checksum으로 확인 결과 정상. 그리고 packet sequence number가 1임을 확인 

- extract(packet, data)(action) : packet에서 data를 추출

- deliver_data(data)(action) : data를 application 계층으로 보냄

- sndpkt = make_pkt(ACK, checksum) : ACK상태, checksum을 포함한 packet 생성.

- udt_send(sndpkt)(action) : sender에게 sndpkt 전송. receiver는 wait for call 0 from above 상태로 바뀜.

 

<statement 상태에서 발생할 수도 있고, 발생하지 않을 수도 있음>

- rdt_rcv(packet) && corrupt(rcvpkt)(event) : ip계층으로부터 받은 packet이 checksum으로 확인 결과 손상 

- sndpkt = make_pkt(NAK, checksum) : NAK 상태, checksum을 포함한 packet 생성.

- udt_send(sndpkt)(action) : sender에게 받은 패킷이 NAK라고 전송

 

- rdt_rcv(packet) && notcorrupt(rcvpkt) && has_seq#(rcvpkt)(event) : ip계층으로부터 받은 packet이 checksum으로 확인 결과 정상. 그러나 sequence number가 #.(#은 중복된 packet의 number.) 

- sndpkt = make_pkt(ACK, checksum) : ACK 상태, checksum을 포함한 packet 생성.

- udt_send(sndpkt)(action) : sender에게 받은 패킷이 ACK라고 전송

 

* rdt 2.2

- NAK가 없는 rdt

- 누적 ack을 사용해서 sender는 마지막 수신한 ACK의 sequence number 이전의 packet은 문제 없음을 확인

- receiver는 NAK 대신 최근에 정확히 수신된 packet에 sequence number가 포함된 ACK를 전달 
- sender는 중복된 ACK를 통해서 중복된 ACK packet 이후에는 packet이 수신되지 못 함을 인식

 

rdt 2.2의 FDM

sender

- wait for call 0 from above(statement) : 상위계층(above)에서 squence number가 0인 packet으로 만들 data를 받는 것을 기다리는 상태

- rdt_send(data)(event) : application계층으로부터 data를 받음.

- sndpkt = make_pkt(0, data, checksum)(action) : data를 squence number가 0, checksum을 포함한 packet으로 만듦

- udt_send(sndpkt)(action) : ip계층으로 packet을 보냄

 

- wait for ACK 0(statement) : sequence number가 0인 ack를 기다리는 상태

- rdt_rcv(rcvpkt) && {isACK(rcvpkt, 1) || corrupt(rcvpkt)}(event) : receiver에게 받은 packet의 ACK sequence number가 1(0번을 못 받았다는 의미). 또는 receiver에게 받은 packet이 응답 자체가 깨져있음.

- udt_send(sndpkt)(action) : ip계층으로 packet을 다시 보냄

- rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isACK(rcvpkt, 0)(event) : receiver에게 받은 packet이 손상되지 않음. 그리고 receiver에게 받은 packet의 ACK sequence number가 0임을 확인. sender는 wait for call 1 from above 상태로 바뀜.

 

receiver

- wait for call 1 from below(statement) : 하위계층(below)에서 sequence number가 1인 packet을 기다리는 상태

- rdt_rcv(packet) && notcorrupt(rcvpkt) && has_seq1(rcvpkt)(event) : ip계층으로부터 받은 packet이 checksum으로 확인 결과 정상. 그리고 packet의 sequence number가 1임을 확인

- extract(packet, data)(action) : packet에서 data를 추출

- deliver_data(data)(action) : data를 application 계층으로 보냄

- sndpkt = make_pkt(ACK1, checksum) : ACK가 1, checksum을 포함한 packet 생성.

- udt_send(sndpkt)(action) : sender에게 sndpkt 전송. receiver는 wait for call 0 from above 상태로 바뀜.

 

<statement 상태에서 발생할 수도 있고, 발생하지 않을 수도 있음>

- wait for call 0 from below(statement) : 하위계층(below)에서 sequence number가 0인 packet을 기다리는 상태

- rdt_rcv(rcvpkt) && {has_seq1(rcvpkt) || corrupt(rcvpkt)}(event) : sender에게 받은 packet의 ACK sequence number가 1. 또는 sender에게 받은 packet이 응답 자체가 깨져있음.

- udt_send(sndpkt)(action) : ip계층으로 ACK가 1인 packet을 다시 보냄

 

* rdt 3.0

- 하위 채널에 packet loss가 일어날 수 있는 경우가 존재. 이 경우에 checksum, sequence number, ACK만으로는 부족 
- sender는 합리적인 시간(RTT보다 조금 더 긴 시간)만큼 ACK를 기다려도 오지않으면 ACK를 재전송. 
- 만일 ACK가 지연된 것이라면 재전송이 일어나 receiver에게 packet이 중복되지만 이에 대한 처리 시스템이 구비되어있어 이러한 작업은 실제로 문제를 일으키지는 않는다. 
- 위의 구현을 위해 countdown timer를 필요.

- receiver는 rdt 2.2와 같다

 

rdt 3.0의 FDM

sender

- wait for call 0 from above(statement) : 상위계층(above)에서 squence number가 0인 packet으로 만들 data를 받는 것을 기다리는 상태

- rdt_rcv(rcvpkt)(action) : 만약 receiver에게 packet을 받아도 무시(일어나지 않을 수 있음)

- rdt_send(data)(event) : application계층으로부터 data를 받음.

- sndpkt = make_pkt(0, data, checksum)(action) : data를 squence number가 0, checksum을 포함한 packet으로 만듦

- udt_send(sndpkt)(action) : ip계층으로 packet을 보냄

- start_timer(action) : packet 보낸후 타이머 시작. wait for ACK 0인 상태로 바뀜

 

- wait for ACK 0(statement) : sequence number가 0인 ack를 기다리는 상태

- rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isACK(rcvpkt, 0)(event) : receiver에게 받은 packet이 손상되지 않음. 그리고 receiver에게 받은 packet의 ACK sequence number가 0임을 확인.

- stop_timer(action) : timer를 멈추고 wait for call 1 from above 상태로 바뀜

 

- wait for call 1 from above(statement) : 상위계층(above)에서 squence number가 1인 packet으로 만들 data를 받는 것을 기다리는 상태

- rdt_rcv(rcvpkt)(action) : 만약 receiver에게 packet을 받아도 무시(일어나지 않을 수 있음)

- rdt_send(data)(event) : application계층으로부터 data를 받음.

- sndpkt = make_pkt(1, data, checksum)(action) : data를 squence number가 1, checksum을 포함한 packet으로 만듦

- udt_send(sndpkt)(action) : ip계층으로 packet을 보냄.

- start_timer(action) : packet 보낸후 타이머 시작. wait for ACK 0인 상태로 바뀜

 

- wait for ACK 1(statement) : sequence number가 1인 ack를 기다리는 상태

- rdt_rcv(rcvpkt) && notcorrupt(rcvpkt) && isACK(rcvpkt, 1)(event) : receiver에게 받은 packet이 손상되지 않음. 그리고 receiver에게 받은 packet의 ACK sequence number가 1임을 확인.

- stop_timer(action) : timer를 멈추고 wait for call 0 from above 상태로 바뀜

 

<statement 상태에서 발생할 수도 있고, 발생하지 않을 수도 있음>

- rdt_rcv(rcvpkt) && {isACK(rcvpkt, 1) || corrupt(rcvpkt)}(event) : receiver에게 받은 packet의 ACK sequence number가 1(0번을 못 받았다는 의미). 또는 receiver에게 받은 packet이 응답 자체가 깨져있음. 딱히 조치를 취하지 않고 무시.

- timeout(event) : 타이머(packet을 기다리는)의 시간 만료

- udt_send(sndpkt)(action) : ip계층으로 packet을 보냄.

- start_timer(action) : 패킷 보낸후 타이머 시작. wait for ACK 0인 상태로 바뀜

 

- rdt_rcv(rcvpkt) && {isACK(rcvpkt, 0) || corrupt(rcvpkt)}(event) : receiver에게 받은 packet의 ACK sequence number가 0(1번을 못 받았다는 의미). 또는 receiver에게 받은 packet이 응답 자체가 깨져있음. 딱히 조치를 취하지 않고 무시.

- timeout(event) : 타이머(packet을 기다리는)의 시간 만료

- udt_send(sndpkt)(action) : ip계층으로 packet을 보냄.

- start_timer(action) : 패킷 보낸후 타이머 시작. wait for ACK 0인 상태로 바뀜

 

rdt 3.0 stop and wait

 - 송수신 시간보다 RTT가 길어서 비효율적

 

RTT(Round Trip Time)

- 패킷망(인터넷)에서 상대측 호스트까지 패킷 왕복하는데 걸리는 시간

- 영향을 주는 요소는 망의 혼잡거리전송속도 등등이 존재.

 

MTU(Maximum Transfer Unit)

- TCI/IP 네트워크같은 패킷 또는 프레임 기반 네트워크에서 전송도리 수 있는 최대 크기의 패킷 또는 프레임

- Syn 패킷을 통해 MSS 값을 조정해 미리 MTU 값을 조정.

- MTU  패킷에 Header 값을 포함합니다.

- TCP는 ACK를 확인  순차적으로 전송하는 반면 UDP 확인만되면 계속해서 전송(신뢰성 통신과 비신뢰성 통신의 차이)

 

MSS(Maximum Segment size)

- MTU에서 각종 Header 제거한 값 한 패킷의 순수한 데이터 크기

- 전송할 데이터가 저장될  있는 최대 길이.

 

window

- MSS 묶음이며, window size는 송신 가능한 mss 묶음의 크기

- window size 제어에는 흐름제어와 혼잡제어가 존재.

- 흐름제어는 receiver가 상한선을 제시 하는 것, 혼잡제어는 sender가 혼잡시 알아서 제어하는 것으로 혼잡제어로 window size를 정하는 경우가 많음

 

* Pipelined protocol

- Pipelining은 sender에게 ACK 가리지 않고 여러개의 packet 송신하게 허용하는 .

- 패킷을 송신할때 마다 sequence number가 증가.

- sender receiver 하나 이상의 packet buffering할 수 있다.

- Go-Back-N 방식과 Selective repeat 방식 2가지가 존재

 

Go-Back-N

- 수신측에 상관없이 송신측에서 처리하는 방식.

- window는 전송 되었지만 확인 되지 않은 packet를 위해 허용할 수 있는 sequence number의 범위를 의미

- window size내의 처음 패킷을 send_base로 지정하고, send_base에만 timer가 존재.

- timeout이 발생하면 ACK가 없는 packet이후 모든 패킷을 재전송하고, ACK를 받게 되면 다른 패킷으로 send base가 옮겨짐

- 통신 중 packet이 손실된 경우에는 해당 packet에 대한 ACK를 수신할때 까지 해당 pkt를 재송신하며 이후에 오는 ACK는 무시하다가 ACK를 수신하면 해당 packet 이후 sequence number를 가진 packet을 모두 재전송 

- 통신 중 ACK가 손실된 경우에는 손실된 ACK의 다음 ACK가 도착한다면 receiver가 손실된 ACK가 정상적으로 수신한 것으로 간주

 

Selective repeat

- receiver가 수신한 packet에 대한 개별적인 ACK를 요구.

- 중간에 packet이 손실되면 소실되면 하위 sequence number를 가진 packet이 수신될때 까지 buffering됐다가 해당 sequence number의 packet이 도착하면 buffering됐던 ACK까지 포함해서 전송.

- sender는 ACK가 없는 packket에 대해서만 재전송을 하며 각각 timer를 유지하고, ACK를 수신한 pkt는 timer를 제거

- sender의 window는 send_base pkt의 ACK를 받아야만 이동.

- 통신 중 packet이 손실된 경우에는 해당 packet에 대한 ACK를 수신할때 까지 window를 받고 window내의 다른 packet에 대한 ack는 저장하다가 ACK를 수신하면 수신한 마지막 ACK의 다음 packet으로 send_base가 이동

- 통신 중 ACK가 손실된 경우에는 손실된 ACK를 받을때까지 window 고정되고 window내 다른 packet의 ACK는 저장. 수신층의 윈도우 사이즈는 계속해서 이동. 만약 window밖에 있는데 그 이전 패킷을 받는다면 해당 패킷에 대한 ACK만 주고 window의 변화는 없음.

'Security > 네트워크' 카테고리의 다른 글

network - transport layer(4)  (0) 2020.02.19
network - transport layer(3)  (0) 2020.02.14
패킷의 이해  (0) 2020.02.11
wireshark 기본 사용법  (0) 2020.02.11
네트워크 - 전자우편&FTP  (2) 2020.02.06