kh교육

(20250812034)DNS 서버 구성, tcp (신뢰적인 데이터 통신)

boangod 2025. 8. 12. 22:43

 

 

실습

 

DNS 서버 구성하기

 

 

 

 

 

stu, st10.stu  만들기

 

 

 

stu → 192.168.10.146

 

 

/etc/named.conf

 

 

/var/named/named.ca

.                        518400           IN          NS         ns.

ns.                    518400           IN           A           192.168.10.106

 

추가해 주기

 

 

/var/named/stu.zone

 

 

systemctl restart named.service

 

 

 

st10.stu → 192.168.10.147

 

 

 

/etc/named.conf

 

 

 

/var/named/named.ca

.                        518400           IN          NS         ns.

ns.                    518400           IN           A           192.168.10.106

 

추가해 주기

 

 

/var/named/st10.stu.zone

 

 

systemctl restart named.service

 

 

tcp

 

rdt 2.2

- NAK가 없는 rdt

 

◆  rdt 2.1과의 차이는 ACKs만을 사용하는 것이다.

◆  receiver는 NAK 대신 최근에 정확히 수신된 pkt에 대한 ACK를 전달한다.

◆ Sender는 중복된 ACK를 통해서 중복된 ACK pkt이후에 전송한 pkt이 정상적으로 수신되지 못했음을 안다.

 

 

ACK0 : 내가 0번까지는 잘 받았다.

 

 

ACK의 누적

 

누적된 ACK를 사용하는 경우 sender는 마지막 수신한 ACK의 seq # 이전의 pkt는 모두 정상 전달 되었음을 확인할 수 있다.

 

 

sender

Wait for call 0 from above    →  시퀀스번호가 0번인 패킷을 보내려고 app가 데이터 주기를 기다리는 상태

 

rdt_send(data)    →  app로부터 데이터를 받는 이벤트가 발생

 

sndpkt = make_pkt(0, data, checksum)    →     시퀀스번호가 0번, 데이터 체크섬을 포함한 패킷을 만듦

 

udt_send(sndpkt)    →     하위계층으로 만든 패킷을 전달

 

Wait forACK 0    →     하위레이어로부터 시퀀스번호가 0번인 패킷에 대한 ACK0이 오기를 기다리는 상태

 

 

rdt_rcv(rcvpkt)        →      하위 레이어에서 패킷을 받음

 

(corrupt(rcvpkt) || isACK(rcvpkt,1))      →      응답이 훼손됐거나, ACK1응답을 전달받음(내가 기다리는 ACK0의 응답은 못 받음)

 

udt_send(sndpkt)      →     받은 패킷을 다시 하위레이어로 보냄

 

Wait forACK 0    →     하위레이어로부터 시퀀스번호가 0번인 패킷에 대한 ACK0이 오기를 기다리는 상태

 

rdt_rcv(rcvpkt)        →      하위 레이어에서 패킷을 받음

 

notcorrupt(rcvpkt) && isACK(rcvpkt, 0)        →     응답이 멀쩡하고 정확한 ACK0 응답을 받음

 

Wait for call 1 from above    →  시퀀스번호가 1번인 패킷을 보내려고 app가 데이터 주기를 기다리는 상태

 

 

이후 과정은 동일하다.

 

 

receiver

 

 

 

Wait for 1 from below     →     하위레이어에서 시퀀스번호 1번 패킷이 올라오기를 기다리는 상태

 

 

rdt_rcv(rcvpkt)         →    하위레이어로부터 패킷을 받는 이벤트 발생

 

notcorrupt(rcvpkt) && has_seq1(rcvpkt)          →     패킷이 깨지지 않고, 시퀀스번호가 1인 패킷인지 확인

 

extract(rcvpkt, data)         →      패킷에서 데이터를 추출

deliver_data(data)         →       추출한 데이터를 app로 전달

sndpkt = make_pkt(ACK1, chksum)         →      1번 패킷을 잘 받았다는 의미로 ACK1과 체크섬을 포함한 패킷을 생성

udt_send(sndpkt)         →      하위레이어로 패킷을 보냄

 

Wait for 0 from below     →     하위레이어에서 시퀀스번호 0번 패킷이 올라오기를 기다리는 상태

 

rdt_rcv(rcvpkt)         →     하위레이어로부터 패킷을 받음

 

( corrupt(rcvpkt) || has_seq1(rcvpkt) )        →     받은 패킷이 손상되었고, 시퀀스 번호가 1인 패킷인지 확인

 

udt_send(sndpkt):  시퀀스번호  0번인 패킷을 기다리고 있으므로, 이전에 성공했던 시퀀스번호 1번 패킷에 대한 ACK 1을 다시 보냄( make_pkt(ACK1, chksum) )

 

Wait for 0 from below     →     다시 하위레이어에서 시퀀스번호 0번 패킷이 올라오기를 기다리는 상태

 

 

 

 

rdt 3.0

패킷이 가다가 손실되는 경우

ㄴ 채널에 error나 loss가 가능

 

 

하위 채널에 packet loss가 일어날 수 있는 경우 (data & ACKs)

• checksum, seq #, ACKs만으 로는 충분하지 않다.

 

sender는 합리적인 시간만큼 ack를 기 다린다.

◆  합리적인 시간만큼 기다려도 ACK가 없으면 재전송한다.

◆  만일 ACK가 지연된 것이라면

      • 중복을 유발하는 재전송이 일어난다. – 이미 중복 처리에 대한 준비가 되어있다.

      • receiver는 중복된 pkt에 대한 ACK를 재전송한다.

      • 이러한 작업은 실제로 문제를 일으키지 는 않는다.

◆  위의 구현을 위해 countdown timer를 필요로 한다.

 

 

 

sender

 

 

 

 

Wait for call 0 from above    →  시퀀스번호가 0번인 패킷을 보내려고 app가 데이터 주기를 기다리는 상태

 

rdt_send(data)    →  app로부터 데이터를 받는 이벤트가 발생

 

sndpkt = make_pkt(0, data, checksum)    →     시퀀스번호가 0번, 데이터 체크섬을 포함한 패킷을 만듦

 

udt_send(sndpkt)    →     하위계층으로 만든 패킷을 전달

 

start_timer   →     timer를 시작

 

Wait forACK 0    →     하위레이어로부터 시퀀스번호가 0번인 패킷에 대한 ACK0이 오기를 기다리는 상태

 

rdt_rcv(rcvpkt)     →    하위 레이어로부터 패킷을 받음

 

( corrupt(rcvpkt) || isACK(rcvpkt, 1) )     →    받은 응답이 깨졌거나 ACK1의 응답을 받음

 

시퀀스번호 0번의 패킷이 아니면 무시함

 

 

timeout 발생

 

udt_send(sndpkt)     →    이전에 만들었던 시퀀스 번호 0번 패킷을 재전송

 

start_timer:  다시 timer 시작

 

 

rdt_rcv(rcvpkt)     →    하위 레이어로부터 패킷을 받음

 

notcorrupt(rcvpkt) && isACK(rcvpkt,0)     →    패킷을 확인해서 보니 응답이 손상되지 않고, ACK0번의 응답을 받음

 

stop_timer : timer를 멈춤

 

 

Wait for call 1 from above    →  시퀀스번호가 1번인 패킷을 보내려고 app가 데이터 주기를 기다리는 상태

 

 

rdt_rcv(rcvpkt)    →    app이 데이터주기를 기다리는 상태이기 때문에 패킷이 들어오면 무시

 

 

rdt_send(data)    →  app로부터 데이터를 받는 이벤트가 발생

 

sndpkt = make_pkt(1, data, checksum)    →     시퀀스번호가 1번, 데이터 체크섬을 포함한 패킷을 만듦

 

udt_send(sndpkt)    →     하위계층으로 만든 패킷을 전달

 

start_timer   →     timer를 시작

 

Wait forACK 1    →     하위레이어로부터 시퀀스번호가 1번인 패킷에 대한 ACK0이 오기를 기다리는 상태

 

rdt_rcv(rcvpkt)     →    하위 레이어로부터 패킷을 받음

 

( corrupt(rcvpkt) || isACK(rcvpkt, 0) )     →    받은 응답이 깨졌거나 ACK0의 응답을 받음

 

시퀀스번호 1번의 패킷이 아니면 무시함

 

 

timeout 발생

 

udt_send(sndpkt)     →    이전에 만들었던 시퀀스 번호 1번 패킷을 재전송

 

start_timer:  다시 timer 시작

 

 

rdt_rcv(rcvpkt)     →    하위 레이어로부터 패킷을 받음

 

notcorrupt(rcvpkt) && isACK(rcvpkt,1)     →    패킷을 확인해서 보니 응답이 손상되지 않고, ACK1번의 응답을 받음

 

stop_timer : timer를 멈춤

 

 

Wait for call 0 from above    →  시퀀스번호가 1번인 패킷을 보내려고 app가 데이터 주기를 기다리는 상태

 

rdt_rcv(rcvpkt)    →    app이 데이터주기를 기다리는 상태이기 때문에 패킷이 들어오면 무시

 

 

receiver

 

패킷이 깨지거나 중복됐을 때만 반응하면 되기 때문에 이전과 다른 점이 없음.

 

 

 


 

Pipelined protocol

ㄴ rtt내에 패킷을 여러 개 보내는 거

 

성능 = rtt안에 패킷이 얼마나 많이 보내느냐

 

 

윈도우 사이즈  = rtt안에 보낼수 있는 패킷 사이즈

윈도우 사이즈는 클수록 좋다.

윈도우 사이즈는 보내는 놈이 결정한다.

sender는 윈도우사이즈를 크게 하고 싶어 한다.

그러면 큐잉지연이 많이 일어난다.

 

1 mss → 패킷 1개

 

네트워크 사이즈는 정해져 있지 않다.

 

리시버가 윈도우 사이즈 상한선을 정해준다.