Search

Transport

네트워크 레이어랑 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의 절반으로 해버린다.