포스팅이 계속 늦어지고 있다. 포스팅을 기다리고 계신는 있을지 없을지 모르는 독자분들에게 죄송하지만 지금 포스팅이 올라오지 않고 있는 이유는 올릴게 없어서다-_- 이유를 아래와 같이 기술해볼까 한다.


1. 마지막 포스팅을 끝으로 네트워크 부분에 대해서는 잠시 포스팅이 멈출 것이라고 말을 했다. 앞으로 올라올 포스팅은 리눅스 커널에 관한 이야기가 될 것이라고도 예고했다. 최근에 공부한 내용은 리눅스 커널의 스케줄링 관련이다. (CFS라는 내용이다.) 조금 더 깊은 수준의 이해가 필요하다고 생각이 된다. 아직까지는... 그래서 함부로 포스팅을 못 하고 있다.


2. 사실 요즘 리눅스 커널 조차도 공부를 많이 못 하고 있다. Maybe 사람들이 바쁘다..ㅠㅠ 


3. 2번의 이유 때문에 나는 평소에도 공부하고 싶었던 System Exploitation을 공부하고 있는데, 그게 또 만만치 않다. Format String Vulnerability를 공부했는데 공부하다보니까 C의 printf 함수를 분석해놔야하고 그걸 분석하니까 구현해서 성공하면 포스팅하려고 하는데 성공이 안된다;;; 


대략 이러한 이유다. 독자분들께 미안하지만 조금만 참아주세요.. 그래도 조만간 포스팅 하나 올라올 수도 있을 것 같습니다(?)

Posted by 빛나유

댓글을 달아 주세요

※ 질문/내용오류/공유할 내용이 있다면 jinkilee73@gmail.com으로 메일 주세요 :-)


드디어 네트워크의 마지막을 장식할 시간이 왔다. 그렇다고 큰 거는 아니고 스스로 계획해놨던 포스팅의 가장 마지막 포스팅까지 왔다는 것이다. TCP/IP를 전체적으로 다른 포스팅에 비해서 꽤나 자세하게 다뤄놓을 계획이었는데 그 마지막까지 온 것이다.


지난 번에 설명했듯이 이번 포스팅에서 설명할 이야기는 Congestion Control이다. Error Control, Flow Control에 이어 TCP의 중요 기능 중에 하나이다.  Congestion Control이란 무엇을 뜻하는 말인가? 말 그대로 혼잡을 제어하는 것이다. TCP는 신뢰성를 기반으로 하기 때문에 그 신뢰성을 만족시키면서 최고의 속도를 내기 위해 Congestion Control을 하는 것이다. 


TCP의 Congestion Control은 다음의 세 단계를 거친다.

Slow Start → Congestion Avoidance  Congestion Detection


마지막 Congestion Detection, 즉, Congestion을 탐지했으면 경우에 따라 Slow Start로 돌아갈 수도 있고 Congestion Avoidance로 돌아갈 수도 있다. 


각 단계별로 설명을 하기 전에 Congestion Control에서 직접적으로 다룰 window라는 것을 이야기해보자. 우선 100MB의 파일을 보낸다고 가정하자. 이 파일을 한 패킷에 넣어서 보낼 수 있을까? 당연히 불가능하다. 그래서 이것을 전송가능한 최대치로 나눈다. 그 최대치를 Maximum Segment Size 즉, MSS라고 한다. 이 사이즈대로 100MB를 아래와 같이 나눈다. 이제 sender의 TCP는 이 각각의 MSS를 receiver에게 보내면 된다. window는 TCP가 보낼 MSS 또는 보냈는데 아직 receiver로부터 ACK를 받지 않은 MSS들의 집합이라고 보면 된다. 아래와 같다.


위의 그림에서 MSS가 1MB라고 가정하여 100칸의 segment가 있다고 치자.(100MB를 보내야 하는 상황이므로) 그 중에서 30MB는 TCP가 보냈고 ACK도 받았다. 30MB부터 보낼 차례인데, TCP는 현재 window size를 10으로 두고 있다. 즉, 지금 현재 TCP가 작업할 segment는 30MB부터 40MB까지 10MB이다. 40MB부터 100MB까지는 아직 untouched 하게 내버려둔다. 자 지금 현재 TCP가 작업하고 있는 10MB 정도의 영역을 우리는 window라고 한다. 조금 더 정확히 말하면 opened window, 즉 열린 window이다. 지금 현재 이 부분으로 작업을 하고 있다는 뜻이다. 그렇다면 closed window는 어디일까? 0MB부터 30MB까지이다. 즉 지금 현재 이미 작업을 마친 부분을 의미한다. 


opened window 부분을 조금 더 자세하게 보자. 빨간 segment 들은 이미 receiver에게 전송을 마친 부분이다. 그러나 아직 ACK를 받지 않아서 opened window 에 포함되어있는 것이다. 주황색 segment들은 아직 receiver에게 보내지 않은 segment들이다. 40MB부터 100MB까지도 아직 보내지 않은 segment들이나 그 부분은 아직은 TCP가 신경쓸 부분이 아니므로 untouched하게 내버려둔다. (여기서 untouched라는 용어는 내가 표현하는 방법일 뿐이지 학술적으로 그렇게 설명하고 있는 용어는 아니다.) window size라는 것은 바로 여기서 말하는 opened window 안에 있는 segment 개수를 의미한다. 여기서는 10개가 되겠다.


자 이제 window 의 개념은 자세하게 설명한 것 같으니 TCP Congestion Control의 첫 단계 SLOW START를 공부해보자. 이 부분은 바로 window size를 1부터 시작하겠다는 뜻이다. 대신에 1부터 exponential 하게 증가하여 congestion window size(cwnd)가 1, 2, 4, 8, 16 .... 과 같이 기하 급수적으로 증가하게 된다. 이렇게 어디까지 증가하는가? ssthresh까지 증가한다. 이는 slow start threshold의 약자이다. 


이 값을 초과하기 전까지 Slow Start를 한다. ssthresh값이 16이라고 가정하고 시간에 따른 Slow Start의 전송량(단위;window)을 보자.



ssthresh값에 도달한 후에는 이제 더이상 Slow Start를 쓰지 말고 Congestion Avoidence를 쓰게 된다. Slow Start에서 window size를 두배씩 급격하게 늘려갔다면 Congestion Avoidence에서는 cwnd를 1씩 차근 차근 늘려간다. 위의 그래프를 이어서 그리면 아래와 같이 그려진다.



Congestion Avoidance는 TCP Timeout이 발생하거나 3 ACKs가 발생할 때까지 지속된다. 3 ACKs가 뭐냐고 물어보는 사람은 아래의 링크를 참고하라.

http://operatingsystems.tistory.com/entry/NW-Flow-Control-and-Error-Control

위의 링크에서 설명하는 3 duplicated ACK를 의미하는 것이다.


Congestion Avoidance는 TCP Timeout이 발생하거나 3 ACKs가 발생하면 멈춘다고 했다. 그 후에 진행되는 것이 Multiplicative Decrease이다. 이 과정이 위에서 말했던 Congestion Detection이다. TCP Timeout이 발생했을 경우에는 Multiplicative Decrease가 발생하면서 cwnd가 1이 되고 Slow Start 부터 다시 시작한다. 반면, 3 ACKs가 발생했을 경우에는 Multiplicative Decrease가 발생하면서 cwnd가 현재 cwnd의 절반이 된다. 그리고 Congestion Avoidance를 시작한다. 이를 그래프로 그리면 아래와 같다.


위의 모든 과정을 Algorithm으로 나타내면 아래와 같다.



요약하면 이러하다. TCP는 데이터를 보낼 때 Slow Start를 통해서 기하급수적으로 보내는 데이터의 양을 늘려간다. 그러다가 어느 수치에 다달으면(threshold) 보내는 데이터의 양을 Congestion Avoidance를 통해 서서히 즐가시킨다. 이 때 마주칠 수 있는 두 가지 경우가 있는데, 첫째로 Timeout이 발생하면 cwnd가 1로 되면서 Slow Start를 다시 시작하고 두번째로 3 ACKs가 발생하면 cwnd가 현재의 cwnd의 절반으로 되면서 Congestion Avoidance를 수행하게 된다.


이게 실제로 쓰이는지 궁금해 사람들을 위해 한가지 예시를 들어보자. 파일 다운로드 받을 때 전송 속도를 보면 답이 나온다. 처음에는 초당 수십 KB씩 받으면서 기하 급수적으로 초당 몇 MB 수준으로 올라온다. 그러다가 전송 속도가 줄었다 늘었다 한다. 그 과정이 결국 TCP의 Congestion Control 과정이다. 


아, 드디어 TCP/IP에서 내가 공부한 부분은 다 설명했다. 사실 하나 더 올리고 싶은 부분이 있다. TCP/IP 관련이 아니라 2계층인 Datalink layer 부분이다. 이 계층은 Error Correction을 지원한다. 즉, 전송 도중에 Error가 발생해서 올바르지 못한 데이터가 도착해도 receiver가 알아서 제대로 고친다는 뜻이다. 막 공부하고 싶어지지 않나?

'Computer Networks' 카테고리의 다른 글

[NW] Congestion Control  (12) 2013.10.01
[NW] TCP Flag  (0) 2013.09.22
[NW] Flow Control and Error Control  (1) 2013.09.17
[NW] TCP and UDP  (1) 2013.09.02
[NW] Transport Layer  (1) 2013.08.25
[NW] Type of Service (Differentiated Service)  (2) 2013.08.21
Posted by 빛나유

댓글을 달아 주세요

  1. 헬렌켈러 2013.10.23 20:29  댓글주소  수정/삭제  댓글쓰기

    막 시작하는 저에게 정말 많은 도움이 됬습니다.
    너무너무 감사하고 고생하셨습니다

  2. 잉잉 2013.10.27 15:56  댓글주소  수정/삭제  댓글쓰기

    처음부터 정독했네요:) 네트워크 전공 학생인데 몇몇 이해안갔던 부분 이해하고 갑니다. 좋은 포스팅 감사해요!!

    • 빛나유 2013.10.28 02:18 신고  댓글주소  수정/삭제

      크~~ 처음부터 정독하셨다니.. 또 감동이네요... 요즘 정말 블로그 뎃글에 힘많이 얻고 삽니다ㅋㅋㅋㅋㅋ 네트워크 전공이시더라도 다른 부분은 꼭 공부하셔야 할 때가 올 거에요ㅋㅋ 다른 부분도 자세하게 정성껏 설명해놨으니 많이 읽어보고 가세요 :-)

  3. 기묘한 2013.12.07 09:42  댓글주소  수정/삭제  댓글쓰기

    잘보고 갑니다
    근데 혹시 두번째 slow start에서는 threshold가 절반이 되었는데 이것에 대한 알고리즘 좀 알려주실 수 있나요? 왜 저기서는 threshold가 절반일때 congestion avoidence로 진입한건가요

    • 빛나유 2013.12.08 22:56 신고  댓글주소  수정/삭제

      안녕하세요!! 우선 이와 같은 질문을 해결하기 위해서 최고의 방법을 알려드릴게요~ 답은 간단합니다. 무조건 커널 소스 들여다보시면 됩니다ㅋㅋㅋ 그 어느 누구의 말보다도 정확한 거라고 생각해요..

      TCP flow control은 커널에서 아래의 경로에 구현되어있어요.
      /net/ipv4/tcp_cong.c

      여기에 보시면 tcp_slow_start라는 함수로 slow start가 구현되어있고, tcp_cong_avoid_ai라는 함수로 congestion avoidance 가 구현되어있어요~
      (참고로 /net/ipv4/tcp_vegas.c에 보시면 베가 알고리즘이라고 해서 베가 알고리즘 만의 congestion avoidance가 구현되어있네요...tcp_vegas_cong_avoid라는 이름으로요)

      아무튼 threshold가 절반으로 되어있는 알고리즘은 /net/ipv4/tcp_cong.c에서 tcp_slow_start 함수를 보시면 되는데요

      if(sysctl_tcp_max_ssthresh > 0 && tp->snd_cwnd > sysctl_tp_max_ssthresh)
      cnt = stsctl_tcp_max_ssthresh >> 1;

      이렇게 구현되어있네요.... 즉, max_ssthresh가 0보다 크고!! sender의 congestion window가 slow start의 최대 임계치 (ssthresh) 보다 크면 무조건 최대치를 절반으로 줄이네요...

      그리고 왜 threshold가 절반일 때 congestion avoidance로 진입하느냐는 질문에 대해서 추측을 해보면...(이부분은 저도 정확히는 못 봤으나)

      분명 어딘가에 slow_start에서 congestion avoidance를 call하는 부분이 있을 겁니다... slow_start 함수에서 이미 절반을 했고(위의 코드에서 >>1 을 했었죠?) 그 다음에 congestion avoidance 함수를 호출했겠죠? 그러면 자연스럽게 threshold가 절반일 때 congestion avoidance로 진입하게 되겠네요~ (이 부분은 확실히 소스코드로부터 확인한게 아니라서 확신은 못 하겠네요ㅋㅋㅋ)

      커널 소스 보시고 연구해보시면 답이 나올겁니다!! 열공하세요!!

  4. bandsi 2014.03.28 11:23  댓글주소  수정/삭제  댓글쓰기

    처음부터 정독했는데,
    알기 쉽게 설명을 잘 해놓으신 것 같습니다.
    (그래도 아직 잘 모르겠는게 많은건 함정..)

    공부하고싶어요!!

  5. 2014.12.08 21:25  댓글주소  수정/삭제  댓글쓰기

    비밀댓글입니다

  6. 김원철 2015.04.12 16:14  댓글주소  수정/삭제  댓글쓰기

    congestion control에서 왜 transport layer에서 하는 건가요?
    network layer와 비교해서 장단점이 무엇인지 알수 있을까요?

    • 빛나유 2015.04.13 11:32 신고  댓글주소  수정/삭제

      network layer의 역할을 생각해보시면 답이 나올 것 같습니다!!
      network layer는 오로지 데이터 전달하는 역할입니다
      우체부가 받은 소포에 내용 검사안하죠? 그런거와 같습니다.

  7. 김원철 2015.04.12 16:16  댓글주소  수정/삭제  댓글쓰기

    현재 인터넷에서는 RFC793을 사용하는 것으로 알고 있습니다.
    그렇다면,, RFC 793에서 다음의 RTO를 계사는데에 있어서 jacobson의 알고리즘을 사용하는데..
    그에 대한 변수를 g= 0.125, h= 0.25, f=4 그리고 exponential averaging에서도 alpha = 0.8~0.9,
    beta = 1.3~2로 추천을 하는데.. 그에 대한 근거가 무엇인지 궁금합니다....

    • 빛나유 2015.04.13 11:37 신고  댓글주소  수정/삭제

      RFC793.. TCP네요....
      jacobson 알고리즘은... 저도 잘모르겠습니다ㅋ
      아마 data communications and networking 라는 책을 찾아보시면 아마 있지 않을까 싶네요.. (확인해본 사항은 아닙니다)

[NW] TCP Flag

Computer Networks 2013. 9. 22. 03:59

※ 질문/내용오류/공유할 내용이 있다면 jinkilee73@gmail.com으로 메일 주세요 :-)


저번 포스팅에서 TCP의 Flow Control과 Error Control을 공부했다. 저번에 말 했듯이, 이번 포스팅에서는 TCP의 Flag에 대하여 설명을 할 예정이다. TCP Flag를 설명하면서 동시에 TCP 헤더에 있는 Flags 필드를 같이 설명할 예정이다.


TCP 헤더에서 TCP Flag는 총 6 비트를 차지한다. 그 6개의 비트는 다음과 같다.


URG, ACK, PSH, RST, SYN, FIN


위의 6비트들이 on/off되면서 어떤 것을 알려주는지 알아보자. 쉬운 것들부터 설명을 해보도록 하자. SYN과 ACK를 먼저 공부해보자. 이것들을 이해하기 위해서는 3 way handshaking을 이해하면 좋다. TCP는 session oriented한 프로토콜이다. 즉, 세션이 맺어져야 TCP를 사용할 수 있다는 이야기이다. 이렇게 TCP를 이용하기위해 TCP 세션을 맺는 과정을 3 way handshaking이라고 부른다. 이 과정은 아래와 같다.


그렇다. 모든 TCP 통신은 위와 같이 TCP 세션을 맺은 후 수행되게 되어있다. 그 내용을 자세하게 들여다 보자. A 패킷을 먼저 보자. 임의로 Seq를 8000으로 세팅하고 보냈다. 유의할 점은 이 패킷은 sender와 receiver 간의 가정 처음에 보낸 데이터이기 때문에 ACK를 설정할 이유가 없다는 것이다. (이 부분이 이해가 안 간다면 이전의 포스팅을 참고해라.) 그리고 A 패킷의 가장 아래 행이 6개로 나뉘어있다는 것에 주목하자. 저 부분이 TCP  Flag의 6 비트라고 하고 이야기해보자. 저 부분을 보면 두번째 오른쪽 칸에 S라고 적혀있다. 저 자리가 바로 SYN 비트의 자리이다. 저 자리의 값이 1로 되어있다는 말은 SYN이 세팅되었다는 말과 동일하다.


B 패킷을 보자. ACK는 당연히 8001이다. 그리고 자기 나름데로 Seq를 15000으로 세팅해서 보내는데, TCP Flag를 보면 ACK와 SYN이 세팅되어있다. ACK는 이전에 sender가 보낸 A패킷에 대한 응답임을 의미하기 위함이다. SYN은 receiver가 처음으로 보내는 SYN이다. 


C 패킷을 보자. ACK만 세팅되어있다. 이는 이전에 receiver가 보낸 B 패킷에 대한 응답이라는 뜻이다. 여기서 중요한 부분은 Seq가 8001이라는 점이다. 간단하게 생각해보자. 앞서 말했듯이 Seq는 보낼 데이터의 시작 바이트이다. 제일 처음에 SYN 패킷을 보냈을 때 8000을 보냈는데 그 때는 아무런 데이터를 보내지 않았다. 그러면 8000이어야 하지 않나? 그런데 왜 8001일까? 내가 참고하는 책에 따르면, 제일 처음 SYN 패킷을 보낼 때 아무런 데이터를 보내지 않음에도 불구하고 1바이트를 보내는 것처럼 작동한다고 한다. 그래서 실제로 보낸 데이터는 없지만 8001로 세팅이되어 3 way handshaking의 마지막 ACK 패킷을 보낸다. 


이것이 데이터를 전송하기 전에 맺는 Connection Establish 과정이다. 다음에 설명할 내용은 데이터 전송 과정이다. 이 부분은 앞에서 Flow Control과 Error Control 과정을 설명할 때 자세하게 설명했다고 생각한다. 추가적으로 설명할 부분이 있다면, PSH 비트정도이다. PSH는 PUSH의 약자이다. 일반적인 책이나 사이트에서 PSH 비트를 설명한 것을 보면 "즉시 데이터를 전송하도록 하는 비트"라고 설명을 한다. 내 개인적인 의견으로는 이렇게 설명을 하면 이해하기 어렵다. 나는 이렇게 설명하고 싶다. MTU가 꽉 차지 않았음에도 그냥 보내도록 하는 비트. 예를 들어 지금 보낼 수 있는 MTU는 1500인데 실제로 보낼 데이터가 700 밖에 되지 않으면 어떻게 해야하나? 꽉 차지 않았음에도 그냥 보내야 한다. 이렇게 패킷의 MTU보다 실제로 보낼 데이터가 적을 때 PSH를 세팅해서 보낸다. 아래와 같다.


이렇게 꽉 채워지지 않은 상태에서 보낸다는 의미는 다르게 해석하면 receiver process에게 최대한 빠르게 데이터를 전달해준다는 의미도 있다. 패킷이 꽉 찰때까지 기다리지 않아도 되니까 receiver에게는 그만큼 더욱 빠르게 도달하겠지.


데이터 전송에 쓰이는 또 다른 TCP Flag 비트는 URG 비트이다. 이는 Urgent 의 약자이다. TCP 헤더에서 Urgent pointer라는 필드가 있다. 이 필드는 반드시 TCP Flag의 URG 비트가 세팅되어있어야 의미가 있는 필드라고 이전에 설명을 다 한 상태이다. 이 비트는 거의 쓰이지 않는다. 아마 보기 힘들거라고 들었다. 정확한 사용법에 대해서는 나도 잘 모르겠다. 우선 이 부분에 대한 자세한 설명은 무기한 연장하겠다.


그 다음 설명할 비트는 FIN 비트이다. Finish의 약자이다. TCP에서 3-way handshaking을 통해 세션을 맺는 과정이 있듯이 세션을 끊는 과정도 있다. 이 과정에서 FIN 비트가 사용된다. 아래와 같다.

위와 같다. 3-way handshaking 과 별반 다를 것이 없다. 굳이 찾는다면 FIN 비트가 SYN 비트 대신에 세팅되었다는 것 정도이다. TCP에서 세션을 맺는 과정은 한 가지 방법 밖에 없다. 그렇지만 TCP에서 세션을 끊는 방법은 위의 방법 이 외에 또 다른 방법이 있다. 흔히 이 방법을 4-way handshaking 이라고 한다. 또 다른 말로는 Passive termination 이라고 불린다. 이 방법은 sender가 receiver에게 종료 요청을 보낸 후에도 receiver는 sender에게 계속적으로 데이터를 보낼 수 있다. 다 보낸 후 receiver가 sender에게 FIN 패킷을 전송한다. 아래와 같다.

이제 마지막 한 비트 남았다. RST. Reset이다. 이것은 그다지 어려운 개념이 아니다. 한마디로 연결을 reset하겠다는 것이다. 이는 주로 invalid한 요청 등이 들어왔을 때 혹은 에러가 발생했을 때 보내진다. 즉 연결 자체를 거부하거나 끊어져야만 할 때 사용된다는 뜻이다.


이로서 TCP Flag에 대한 설명은 모두 마쳤다. 정리해보자. SYN은 Connection Establishment에서 사용하고 PSH, URG는 데이터 전송에 사용하고, FIN은 Connection Termination에 사용하는데 각 과정에 대한 응답은 모두 ACK를 통해 이루어진다는 것이다. 마지막으로 에러 혹은 connection refuse 등이 발생할 때는 RST를 통해서 이루어진다.


이제 TCP/IP 포스팅의 거의 마지막에 왔다. 아직까지 설명하지 못한 TCP 헤더의 내용이 있다면 Window size이다. Window size는 앞서 계속 한번씩 언급했지만 딱히 지금까지 다뤄지지 않았다. 다음 포스팅에서 제대로 다뤄볼 생각이다. TCP의 또 다른 Control 능력인 Congestion Control을 통해서 이야기 해보려고 한다. 이 포스팅만 끝나면 드디어 내가 더욱 하고 싶은 Linux Kernel에 대한 포스팅을 시작할 수 있다. 앗싸~

'Computer Networks' 카테고리의 다른 글

[NW] Congestion Control  (12) 2013.10.01
[NW] TCP Flag  (0) 2013.09.22
[NW] Flow Control and Error Control  (1) 2013.09.17
[NW] TCP and UDP  (1) 2013.09.02
[NW] Transport Layer  (1) 2013.08.25
[NW] Type of Service (Differentiated Service)  (2) 2013.08.21
Posted by 빛나유

댓글을 달아 주세요