네트워크 레이어랑 transport layer의 차이
•
네트워클 레이어는 host 간의 통신
•
transport layer는 프로세스 간의 통신
Multiplexing, Demultiplexing
•
multiplexing: 여러 소켓에서 오는 데이터를 다루는 것. transport header를 더함
•
demultiplexing: 이 헤더를 이용해서 정확한 socket에 보내주는 것
◦
TCP는 (source IP, source port, dest IP, dest port) 이 4가지 정보로 이루어진 튜플로 소켓 하나가 구성됨. 아래 그림처럼
•
UDP는 (destIP, dest port) 이것 만으로 소켓을 하나 할당함. 그래서 아래 그림처럼 돌아감
UDP
•
connectionless
◦
no handshaking 이다
◦
각 세그먼트들은 독립적으로 다뤄진다
◦
no congestion control
▪
가장 빠르게 도달할 수 있을대로 도달한다
•
checksum
◦
detect error
◦
2개의 4bit를 보낸다고 하면, 그걸 더한 값의 1의 보수를 같이 보냄
◦
받은 데이터랑 보낸 보수랑 더해서 1111이 되면 correct 아니면 uncorrect
Reliability
이상적인 채널 조건에서 하나씩 제거해나가면서 FSM을 그려가보자
1.
reliable channel
•
그냥 보내고 받으면 됨.
2.
bit error가 있다고 생각
•
checksum으로 detect 하면 되는데, 어떻게 recovery를 하나
•
감지하면 다시 보내라고 한다.
•
만약에 ACK,NACK가 corrupted 되면 어떻게 하냐?
◦
그냥 무작정 다시 보낼 수는 없다. 중복될 수 있기 때문에
◦
일단 ACK/NACK가 corrupted 됬다면 sender는 다시 보낸다. 근데 sequence number랑 함께 보냄
◦
receiver가 그걸 보고 duplicate 된거면 discard한다.
3.
rdt2.1이 등장 ← ACK/NACK이 손상될 수 있다는 가정
4.
NAK 없이 구현한 버전
•
NAK 없이 자기가 받은 마지막 패킷 시퀀스의 ACK만 반복해서 보낸다.
•
ACK 1 이렇게 시퀀스를 포함해서 보냄
5.
채널 자체가 패킷을 드랍할 수도 있다고 가정.
a.
checksum이나 sequence 숫자, 재전송이 도움이 될 수 있지만, 충분하지 않음
b.
timer를 설정해서 합리적인 시간동안 기다린다.
•
근데 성능이 엄청 안 좋음. 아래 그림 처럼 stop-wait을 하기 때문에 utilization이 엄청 떨어진다.
•
이것 때문에 pipelining을 한다.
◦
pipelining을 할 때는 go-back-N, selective repeat 등을 하게 된다.
◦
여기서 파이프라이닝은 일단 오지 않아도, 일단 한 번에 쭈욱 다 보내는 것. 위에서 언급한 2가지 방식은, 순서가 어긋난 것에 대해서는 어떻게 할 것인가를 다룬다.
Pipelining
•
Go-back-N
◦
N개를 동시에 보낸다.
◦
수신자는 누적 ack을 보낸다. 그러니까 순서가 맞는 것들 중 제일 위쪽을 보낸다.
◦
송신자가 타이머가 있어서, 그게 만료되면 unack 된 거를 다 같이 보낸다.
•
selective Repeat
◦
송신자가 N개를 동시에 보낸다
◦
수신자는 개별적으로 ACK 함.
◦
송신자는 unack 된 패킷에 대해서 타이머를 유지한다. 만료되면 재전송함.
◦
도착하면 sender의 window를 당김
TCP Connection
어떻게 현망하게 timeout을 정할 것인가?
•
RTT 보다는 길어야 할것
◦
근데 RTT가 계속 바뀐다.
•
너무 짧으면, 이른 timeout을 하게 되고 계속 다시 보낸다
•
너무 길면, loss에 대해 slow reaction을 한다
•
어떻게 하냐?
◦
sample을 한다. 그리고 exponential weighted moving average
◦
여기에 조금의 마진을 덧붙여서 보냄
•
기다리지 않고 빠르게 재전송하는 경우도 있음
◦
3번 연속 같은게 오면 retransmit 함
Flow control
•
패킷 헤더에 포함함. 수신자에게 남은 버퍼의 크기를 보냄
•
송신자는 항상 조건을 만족해야함.
◦
마지막으로 보낸거에서 내가 받은거를 뺀 양이 rwnd를 넘지 않도록
Connection management
•
2-way로는 충분하지 않다.
◦
상대방에게 패킷을 전달할 수 있다.
◦
상대방으로부터 패킷을 전달받을 수 있다.
◦
근데 2-way에서는 클라이언트는 둘 다 확인할 수 있지만, 서버는 2만 확인 가능함.
•
왼쪽
◦
연결에 대한 응답이 타임아웃이 되면, 클라이언트는 안 되서 연결을 종료할 거고 그래서 서버만 연결되었다고 생각할 수 있음
•
오른쪽
◦
오른쪽에서는 클라가 커넥션이 됬다고 생각해서 데이터를 보내면 두 번 올려보낼 수 있다.
Closing
•
Client, Server가 각각 닫아야 한다.
◦
각각 보내는 걸 멈춰야하기 때문. 받는거랑은 별개가 되야한다.
Congestion Control
•
네트워크가 감당가능한 것보다 더 많이 보내는 것
◦
router buffer에 큐잉이 됨 → 엄청 긴 대기
◦
라우터에 버퍼가 오버플로우임 → 패킷 lost
•
finite buffer인 경우부터 loss가 발생하는데, 이러면 송신자가 여러 번 보내게 된다.
•
따라서 실제보다 들어가는 양이 더 많아지고, 그에 따라 받는 양이 일정하게 증가하지 않는다.
◦
왜냐하면 중복임을 알고 수신 쪽에서 제거하기 때문에
◦
따라서 전체 capacity를 잘 활용을 못하는 것이다.
•
multi-hop인 경우는 더 복잡해지는데,
◦
빨간색 경로가 커지면 파란색 경로는 진입을 못함.
◦
그리고 패킷이 드랍이 되면 사실상 들어가는 양에 비해서 나오는게 없어서 다 드랍되는거라 0으로 throughput이 떨어짐. 여러 개를 거치기 때문에 중간 한군데에서 드랍을 하면 그 이전에 거쳤던 것도 소용이 없던 것이 됨.
•
해결법
◦
AIMD: 증가는 additive, 감소는 multiplicative
◦
slow start: exponentially로 first loss가 생길 때까지 일단 증가함.
▪
첫 rate는 느리지만, 급격하게 빨라진다.
▪
손실 감지
•
Timeout
◦
네트워크가 과도하게 혼잡해서 ACK가 안오는 것으로 판단.
◦
cwnd를 1MSS로 리셋 → 그래도 금방 다시 늘어날 거임
•
중복 ACK
◦
일부 세그먼트가 손실되었다는 것
▪
reno
•
cwnd = cwn/2 + 3MSS
•
이후 선형 증가
▪
tahoe
•
무조건 cwnd = 1MSS 로 리셋
◦
Congestion Avoidance로 전환하기
▪
혼잡 발생 전 속도를 조절하는 것
▪
exponential 하게 보내다가 linear로 바꿈
▪
cwnd가 특정 threshold에 도달하면 그렇게 해야한다.
▪
ssthresh의 경우 loss가 생기면 cwnd의 절반으로 해버린다.
◦