현재 우리가 사용하는 인터넷 모델인 TCP/IP가 어떻게 혼잡도를 조절하는지 알아보자.
먼저 TCP는 데이터를 보내는 sending 버퍼와 데이터를 받는 receiving 버퍼로 나뉜다.
sending 버퍼가 데이터를 보내면 receiving 버퍼는 데이터를 받아서 어플리케이션으로 전달한다.
이때 receiving 버퍼가 어플리케이션으로 전달하는 속도와 sending 버퍼가 데이터를 전송하는 속도가 다를 수 있는데, 이때 sending버퍼의 속도가 빨라서 receiving 버퍼가 꽉차게 된경우 추가적인 패킷이 버려지게된다. 그래서 receiving 버퍼는 sending버퍼에게 자신의 버퍼의 빈공간을 알려주는데 이 값을 windowSize라고 한다.
sending 버퍼는 받은 windowsize를 기반으로 데이터의 전송속도를 조절한다.
패킷의 헤더크기에 비해 보내는 데이터가 매우 작아서 비효율이 발생할 경우를 말한다. 이것을 해결하는 3가지 방법이 있다.
송신측에서 어플리케이션이 전달해주는 데이터가 매우 작은경우
해결방안 : 첫 패킷은 무조건 바로 보내고, 두번째 패킷부터는 기다렸다가 데이터가 MSS(maximum segment size)만큼 쌓일경우 보낸다.
단. 일정시간 동안 패킷이 꽉차지 않을경우에도 보낸다.
수신측에서 어플리케이션이 데이터를 매우 조금씩 처리할경우 리시빙버퍼가 꽉차게 된다.
해결방안 : 윈도우사이즈를 0 설정해서 송신측에 전달.
충분한 빈공간을 확보할때까지 0으로 전달
수신측, 위와 동일
해결방안 : ACK을 늦게보낸다. 송신측 버퍼는 전에 알려준 windowsize만큼 보낸후 대기함.
DOS 방법중 하나.
서버가 클라이언트와 연결하기 위해서는 listen 함수를 호출해서 연결요청대기큐를 만들어야한다. 그후 클라이언트가 연결요청을 할 경우 accept 함수를 호출해서 요청을 허락할경우 연결된다.
이를 악용해서 클라이언트가 자신의 IP또는 포트를 변경한후 서버에 listen요청을 여러번 보내는것이다. 서버의 연결요청대기큐가 꽉차게 되면 서버는 다음에 들어노는 요청을 버리게 된다.
구체적으로 공격자는 SYN을보내고 서버가 SYN+ACK을 보내줄때, ACK으로 응답하지 않고 그 상태를 유지한다. 그럴경우 서버는 연결요청대기큐에서 그 요청을 없애지 않고 대기하게 된다.
Rule 1~3은 기본적인 ACK 전송에 관련된 규칙
Rule 4~6은 ACK의 데이터가 잘못왔을때 대응하는것과 관련된 규칙이다.
네트워크가 연결되기 위해서 네트워크 장비들을 통과해야한다.
그 장비가 가지고 있는 한계점에 도달할경우 생기는것이 네트워크 혼잡(Congestion)이다.
기본적으로 flow control과 구분을 잘 해야한다.
flow control은 리시빙버퍼와 샌딩버퍼 사이의 전송 컨트롤이고
congestion control은 네트워크 장비에서 생기는 문제이다.

이와같이 라우터가 최대 100Mbps를 출력하지만 받는 데이터가 200Mbps가 되면 라우터 버퍼에 쌓이게 되고 버퍼가 가득차면 추가적으로 더 이상 패킷을 받을 수 없게된다.

라우터에서 패킷을 버리게되면 리시빙 버퍼가 데이터를 정상적으로 받지 못하게되고 리시빙버퍼가 보내는 ACK도 정상적으로 도착하지 못하게되면서 다시같은 데이터를 전송하고, 리시빙버퍼는 ACK을 계속 요청해 혼잡도가 더 증가하는 악순환이 반복된다. 위 그래프는 일정 수준까지는 혼잡도가 천천히 증가하다가. capacity에 가까워질수록 딜레이가 급격하게 증가하는것을 보여준다.
따라서 적당수준 네트워크 혼잡도를 유지하는것 BEST이다.
하지만 인터넷은 중앙통제가 없는 방식이기 때문에 현실적으로 쉽지않다.
샌딩버퍼와 리시빙버퍼가 연결이 완료되서 데이터를 전송하기 시작할떄 샌딩버퍼가 하는것이 Slow Start이다. 1부터 2배씩 데이터 전송량을 2배씩 늘려가면서 전송하는것이다. 데이터를 보내고 ACK을 받는 한 주기를 RTT라고하고 RTT마다 보내는 데이터량이 2배씩 증가하게 된다. 최대 미리설정되어 있는 threshold값까지 증가한다.
threshold 값이후는 RTT마다 패킷의 양을 1개씩 증가시킨다.
최대 congestion이 생길때까지 (3 dulplicate ACKs)

그림에서 눈여겨볼것은 3ACK이 검출될경우 단순히 보내는양을 반으로 줄이지만 time-out (즉. 보낸데이터에 대한 ACK이 일정시간이 지나도 오지 않는경우)의 경우 다시 보내는데이터양을 0으로 설정하게 된다.


네트워크연결이 길게 지속될수록 클라이언트끼리 보내는 양이 비슷해지게 된다.
C1과 C2가 보내는양이 각각 80,20이라 가정할때 혼잡이 생겨서 각각 반으로 줄게되면 40, 10으로 줄어들고, 여기서 +1씩하다가 65, 35일때 반으로 줄어들게된다. 32.5, 17.5로 줄어들게되고 57.5, 42.5로 점점 50:50으로 가까워지는것이다. 위 그래프를 보면 y=x 그래프에 점점 까지워 지는것을 볼 수 있다.