TCP의 이상한 행동

urmajest의 이미지

TCP의 경우 slow start일때나 congestion avoidance일때나

cwnd를 줄이는 건 항상 패킷 로스가 발생했을 때라고 알고 있습니다.

그래서 실험을 해봤는데요.

호스트 A에서 호스트 B로 100Mbyte 파일을 TCP로 전송을 하고

ethereal을 이용해서 duplicate ack을 체크를 해보았는데,

duplicate ack이 하나도 없네요. 그 말은 lost packet이 하나도

없고 재전송도 되지 않았다는 뜻인데..

어떻게 이런 시나리오가 가능하죠?

TCP는 패킷 로스가 발생하지 않으면 계속해서 보내는 양을

늘여나갈텐데..

테스트는 리눅스 2.4.x 와 2.6.x에서 해보았습니다.

sangheons의 이미지

재미있는 실험이군요.
일단 생각나는 것은 두가지 가능성이 있을 것 같습니다.

1. Slow start에서 cwnd 사이즈가 무한대로 증가하지는 않습니다.
receiver의 최대 윈도의 사이즈(awnd)보다 작을때까지만 증가하고
그 이상 커지지는 않을 겁니다.
즉, 네트워크 상태가 아주 좋아서 awnd 사이즈로 항상 송신하는데
문제가 발행하지 않는다면 이러한 현상이 나타날수 있겠네요.

2. slow start, congestion avoidance 모두 지정된 timeout 안에
ACK를 받지 못하면 cwnd를 줄이는 동작을 하게됩니다. 즉, 전송지연
이나 처리지연등의 이유로 timeout안에 ACK를 받지 못해도 패킷 손실로
간주하고 동작합니다.
단, 이 경우 좀 의문스럽게 느껴지는 것은 이럴경우 동일한 패킷에 대한
재전송이 일어나므로, duplicate ACK가 수신될 가능성도 어느정도는
있다는 점입니다만.... 수신단에서 패킷 손실이 아니라 동일한 패킷이
수신되었을 때도 바로 duplicate ACK를 전송하는 지는 문서를 좀더 찾아
봐야겠네요.

오랜만에 재미있는 문제로 고민하네 되네요.

tinywolf의 이미지

구현이 덜된거 아닐까... 8)

(그냥 웃자고 한 소리입니다.. ==3 =3 =333 )

ㅡ_ㅡ;

urmajest의 이미지

sangheons wrote:
재미있는 실험이군요.
일단 생각나는 것은 두가지 가능성이 있을 것 같습니다.

1. Slow start에서 cwnd 사이즈가 무한대로 증가하지는 않습니다.
receiver의 최대 윈도의 사이즈(awnd)보다 작을때까지만 증가하고
그 이상 커지지는 않을 겁니다.
즉, 네트워크 상태가 아주 좋아서 awnd 사이즈로 항상 송신하는데
문제가 발행하지 않는다면 이러한 현상이 나타날수 있겠네요.

2. slow start, congestion avoidance 모두 지정된 timeout 안에
ACK를 받지 못하면 cwnd를 줄이는 동작을 하게됩니다. 즉, 전송지연
이나 처리지연등의 이유로 timeout안에 ACK를 받지 못해도 패킷 손실로
간주하고 동작합니다.
단, 이 경우 좀 의문스럽게 느껴지는 것은 이럴경우 동일한 패킷에 대한
재전송이 일어나므로, duplicate ACK가 수신될 가능성도 어느정도는
있다는 점입니다만.... 수신단에서 패킷 손실이 아니라 동일한 패킷이
수신되었을 때도 바로 duplicate ACK를 전송하는 지는 문서를 좀더 찾아
봐야겠네요.

오랜만에 재미있는 문제로 고민하네 되네요.

1. slow start시에는 cwnd가 exponential하게 증가하고, cwnd가 ssthrash(66536bytes) 이상이 되면 congestion avoidance(TCP reno)로 돌입하게 되죠. congestion avoidence상태에서는 매 ack마다 cwnd를 하나씩 증가하구요. 그리고 sender는 awnd(receiver의 window size)와 cwnd의 최소값만큼 한번에 최대로 전송하게 됩니다.
cwnd가 더이상 자라지 않는 것은 아닌 것 같아요.


사실은 상당히 overprovisioned 되어있는 network에서 실험을 하고 있는데요,
호스트 A (Fast Ethernet) - 2G - 10G - 1G - 호스트 B(Fast Ethernet)

이런 상황입니다. 스위치는 10개 정도 거쳐가구요.

RTT가 매우 짧고 (<1ms) overprovisioned된 상황이라고해도 packet loss가 발생하지 않는다는 점은 이상하네요.

1Gbytes 파일을 전송하면서 패킷을 캡춰한 후, ethereal과 tcptrace로 retransmission frame을 찾아보았지만 하나도 없구요.

throughput은 초기 slow start시에 꾸준히 증가하다가(exponential하게) 9xMbps에서 일정하게 유지됩니다.

혹시 관심이 있으시다면 제가 헤더 부분만 캡춰해서 파일을 올릴께요 ^^

sangheons의 이미지

제 표현에 문제가 있었군요. cwnd 사이즈가 더이상 증가하지 않는게 아니라,
실제로 전송에 사용되는 윈도우 사이즈가 awnd보다 커지지 않는게
맞습니다.

throughput이 초기 slow start시에 꾸준히 증가하다가 일정하게 유지된다고
하셨는데, 아마 이러한 논리로 어느정도 설명이 될 것 같습니다.

다른 트래픽에 의해서 Congestion이 발생하지 않는 실험환경이라면 packet
loss를 보기가 쉽지 않을 수 있습니다.
1Gbytes의 데이터를 전송한다고 할때, 유선망에서의 일반적인 비트
에러율인 10^-9을 적용하면 대충 8비트의 에러가 발생합니다.(헤더 및 트레일
러부분 무시)

1G x 8 x 10^-9 = 8

하지만, 이마저도 이더넷 트레일러의 CRC32 필드에 의해서 일부는 바로
정정이 되어버립니다. 확율적으로 본다면 대부분 정정된다고 볼수 있겠지요.
TCP나 IP헤더의 checksum은 에러정정 기능이 없으니 상관없습니다만.

따라서, 링크의 품질이 특별히 나쁘지 않다면, 비트에러에 의한
TCP packet loss는 발생하지 않을 수도 있다고 보입니다.

urmajest의 이미지

sangheons wrote:

다른 트래픽에 의해서 Congestion이 발생하지 않는 실험환경이라면 packet
loss를 보기가 쉽지 않을 수 있습니다.

하지만, 이마저도 이더넷 트레일러의 CRC32 필드에 의해서 일부는 바로
정정이 되어버립니다. 확율적으로 본다면 대부분 정정된다고 볼수 있겠지요.
TCP나 IP헤더의 checksum은 에러정정 기능이 없으니 상관없습니다만.

따라서, 링크의 품질이 특별히 나쁘지 않다면, 비트에러에 의한
TCP packet loss는 발생하지 않을 수도 있다고 보입니다.

CRC는 error detection을 합니다.

패킷의 계산된 CRC와 CRC필드 값이 틀리면 그냥 드랍을 시키지요. 정정 기능은 없구요.

TCP에서는 packet loss를 congestion에 의한 packet loss라고 간주하고 있습니다. 말씀하셨듯이 bit flip에 의한 에러는 매우 드물죠.

bandwidth-full이 넘어서는 traffic을 보내면 packet loss(by congestion)가 일어나므로 그걸 감지할 수 있다는 논리이지요.

제가 실험한 결과에서는 receiver의 wnd가 항상 넉넉하고,

packet loss가 발생하지 않으므로 cwnd가 계속 증가하게 되고,

이런 상황에서는 9xMbps의 일정한 throughput이 유지 될 수가

없는 것이 아닌가하는 것이 의문이네요.

sangheons의 이미지

CRC는 1bit 에러에 대한 자체 정정기능이 있습니다. 2bit 이상의 복수개의
에러에 대해서는 검출만이 가능합니다만.

receiver의 awnd값은 계속 증가하지 않을 겁니다. 수신측의 패킷처리
속도와 관련이 있으니까요.

따라서, 송신측의 cwnd값이 계속 증가하더라도 어느 지점 이후부터 실제로
패킷을 전송하는데 사용되는 윈도의 크기는 cwnd가 아닌 고정된 awnd값이
사용된다고 가정할수 있습니다.
전송 윈도우 사이즈가 고정되어 있고, 링크의 available bandwidth가 이에
의한 트래픽을 전송하는데 충분하다면 thoughput이 일정하게 유지되는 점은
설명이 가능합니다.

urmajest의 이미지

sangheons wrote:
CRC는 1bit 에러에 대한 자체 정정기능이 있습니다.

수업 시간에 배웠던 것과는 다른 내용이네요. 혹시 관련 내용을 링크해 주실 수 있으신가요?

아무리 구글을 뒤져봐도 관련 내용을 찾을 수가 없네요. 상식적으로 1 bit error correction이 가능하다는게 이해가 안 되네요 -_-

sangheons wrote:

전송 윈도우 사이즈가 고정되어 있고, 링크의 available bandwidth가 이에
의한 트래픽을 전송하는데 충분하다면 thoughput이 일정하게 유지되는 점은
설명이 가능합니다.

네. 그런데 그건 몇 가지 더 테스트를 해보면 아닌 걸 알 수 있더라구요. 이론적으로 반대 예을 들자면,

말씀하신 내용은 (receiver window) / (RTT)가 우연히도 9xMbps가 되었다는 것인데, 캡춰된 내용을 보면 receiver window size는

항상 127504bytes로 유지되고 있고,

 (estimated throughput) = (receiver wnd) / (average RTT)
                                = 1.02Gbps

가 되네요. 뭔가 다른 가능한 시나리오가 있을까요?

sangheons의 이미지

어쩌면 아주 단순한 사실을 놓치고 있는 기분이 드네요.

호스트들이 Fast Ethernet에 연결되어있다고 하셨는데, 호스트들이
100Mbps Fast Ethernet 카드를 사용하고 있다면 원인은 아주 간단...할
수 있습니다.

하드웨어의 한계를 넘어서는 전송 속도가 나올수는 없고, 100Mbps 카드에서
9xMbps대의 throughput이 나오고 있다면 아주 양호한 것으로 볼 수
있습니다.

호스트가 직접 연결된 네트워크의 전송 속도를 한번 확인해 주시겠습니까?

urmajest의 이미지

sangheons wrote:
어쩌면 아주 단순한 사실을 놓치고 있는 기분이 드네요.

호스트들이 Fast Ethernet에 연결되어있다고 하셨는데, 호스트들이
100Mbps Fast Ethernet 카드를 사용하고 있다면 원인은 아주 간단...할
수 있습니다.

하드웨어의 한계를 넘어서는 전송 속도가 나올수는 없고, 100Mbps 카드에서
9xMbps대의 throughput이 나오고 있다면 아주 양호한 것으로 볼 수
있습니다.

호스트가 직접 연결된 네트워크의 전송 속도를 한번 확인해 주시겠습니까?

네. 아마도 그것이 문제였던 것 같네요. TCP에서 send할때 blocking call이라면 설명이 가능하네요.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.