TCP/IP 스택 소스좀 살펴보고 있는데요..

jika의 이미지

페킷이 조각나서 전달되오면 순서가 바껴서 도착할수 있잖습니까?

그럼 시퀀스 넘버를 확인해서 리오더링을 해서 조합해야 할텐데요

이 리오더링에 관련된 알고리즘이 알고 싶어서 소스를 보려고 하는데

안 찾아집니다.

TCP 단에서 하는지 IP단에서 하는지도 잘 모르겠구요 -_-;

리눅스 소스하고 xinu 소스를 참고 하고 있습니다만...

경험이 있으신분들은 조그만 조언이라도 부탁드립니다.

익명 사용자의 이미지

ip및 tcp단 두부분에서 수행해야합니다.

ip에서 발생가능한 fragment를 refragmentation하는 프로그램을 작성하고,
tcp에서 stream으로 reassemble하도록 또 만들어야 합니다.

그래서, ip단 tcp단에서 2번을 해줘야합니다. udp의 경우는 ip단에서만 하면되고,
ip라면, ip단 처리만 해주면되겠습니다. tcp/ip가 아닌것은 해당 프로토콜의 스펙에 따라 달라지겠습니다.

참고는, libnids라는 라이브러리, libpal이라는 라이브러리, snort의 frag2, stream4모듈, ethereal....
참 많군요.
그리고, tcp/ip프로토콜 스택 소스를 보는것도 별로 나쁘지 않겠구요.
다 짜면 공개해주세요 ~ ㅎㅎ

그럼 20,000

익명 사용자의 이미지

참고로, 커널 소스에서 net/ipv4/ip_input.c파일에서는 defragment를 수행합니다. 이는 로컬로 오는 트래픽인 경우 수행하게 되는 모듈입니다.
그래서, 로컬로 오는 트래픽의 경우 NF_IP_LOCAL_IN에서 hooking하면 defragment된 ip패킷을 잡을 수 있습니다. tcp reassembly는 그래도 여전히 필요하게 되겠습니다.

jika의 이미지

네트워크쪽 내공이 부족해서 좀더 봐야겠습니다.

답변 감사합니다. 살펴보겠습니다.

다른분들도 좋은 의견 주시면 감사할께요..

partout의 이미지

snort에서는 IP Frag나 TCP Reassembly를 처리하기 위해서 splay tree 라는 알고리즘을 사용하더군요.

가장 나중에 도착한 패킷이 트리의 가장 상위에 위치하게 하는 균형 트리(balanced tree)의 일종이라고 들었습니다.

어찌나 졸린지..~~

jika의 이미지

앞길이 구만리인데 이상한 일에 휘말려서 잠시 본말이 전도된 시간을 보내고 왔습니다.

지금까지 살펴본것 정리차원에서 남깁니다.

손님님 께서 남기신 글 바탕으로 소스들을 살펴 보았습니다.

라이브러리도 다운받고 했는데 역시 제 입장에서는 생소하기는 마찮가지라서

일단 IP 단 커널소스부터 살펴 봤습니다..

함수 단위로 정리해서 남깁니다. 혹 지적할 부분 있으면 꼭 좀 부탁드리겠습니다.

ip_input.c
ip_fragment.c

두가지 파일을 살펴 보았습니다.

ip_rcv ()
메인 IP receive 루틴
잘못배달된 페킷을 걸러내고
헤더의 에러를 체크
체크섬 확인
ip_rcv_finish 콜

ip_rcv_finish -> ip_route_input (멀티케스팅관련) -> ip_route_input_slow (로컬로 배달되는 메세지라면) -> ip_local_deliver -> ip_defrag

ip_defrag ()
메모리를 클린업 하고
큐의 헤더를 확인해서 만들고
ip fragment 를 ip_frag_queue() 를 통해 큐에 집어넣는다.
최종적으로 ip_frag_reasm() 콜하며 리턴한다.

ip_frag_reasm()
큐에 들어온 모든 ip fragment 를 조합해서 새로운 ip 데이터그램을 만든다.

여기까지 입니다.

여기까지 상황에서 제가 다음에 봐야 할부분은 각각의 조합된 UDP 페킷들을

시퀀스 순서에 맞게 리오더링 하는 부분인데요..

이건 제가 지금까지 알아본봐대로라면 커널에서 하지 않고

어플리케이션에서 하는걸로 아는데 (Udp의 경우 입니다.)

적당한 참고 할만한 소스좀 소개해주시면 감사하겠습니다.

여기에 글남겨주시는 모든분들께 행운이 깃들기를..

익명 사용자의 이미지

jika wrote:

...
여기까지 상황에서 제가 다음에 봐야 할부분은 각각의 조합된 UDP 페킷들을

시퀀스 순서에 맞게 리오더링 하는 부분인데요..

이건 제가 지금까지 알아본봐대로라면 커널에서 하지 않고

어플리케이션에서 하는걸로 아는데 (Udp의 경우 입니다.)


IP단에서 defragment되었고, .....

그런데, UDP패킷에는 순서를 표시하는 시퀀스가 없습니다.
포맷 자체가 source port , destination port, length, checksum밖에 없습니다. sequence는 없습니다.

이로인해, UDP는 순서조정을 보다 상위에서 할 수 밖에는 없습니다. 하겠다면, 완전 응용단에서 하겠지요.
또한, 특정 UDP datagram이 손실(송수신컴퓨터, 라우터) 될수 있습니다. 이또한 순서를 조정하지 못하는 요인이됩니다.

그래서, UDP는 사용자 수준(응용프로그램수준)에서 이를 극복하도록 코딩합니다. 응용프로토콜 나름이겠지요. 만일 그 응용프로토콜이 다수개라면 그때 그때 다르게 코딩해야 할것입니다. 해당 응용프로토콜 스펙문서를 보면서,.....

만일 UDP에 순서를 부여하고 TCP처럼 ... 하고 싶다면,고려를 해야하는데, 이를 위해 고려할 문제는 시간, 순서, 손실에 대한 대처입니다.
해결은 재전송, 타임아웃, ARQ전략등입니다.
즉, 패킷 보내고 상대측에게 잘받았다는 응답메시지(Acknowledge)를 받는 것입니다. 또한 순서를 고려하기 위해, 각 UDP패킷에 순서번호를 부여합니다. 매 패킷을 송신시 타임아웃을 걸어둡니다. 일정시간동안 응답이 없으면 재전송하겠다는 것이지요.
이런 얘기들은 통신전공책에 더 잘 나왔고,...
대역폭의 활용을 위해 ARQ전략을 고려할 수 있습니다. 하나보내고 응답받기, 여러개를 연속적으로 보내고 응답받기,
버퍼를 고려해(송수신) 연속적으로 보내고 받기(슬라이딩 윈도우)등을 고려할 수 있겠습니다.
아~ 이런 복잡한 일을 다 해놓은 것이 있으니, 그게 TCP지요.

jika wrote:

...
적당한 참고 할만한 소스좀 소개해주시면 감사하겠습니다.
...

그래도 UDP로 잘~ 보내고 받기를 원하는 경우가 있겠습니다.
보통 TCP에 견주어 UDP를 비신뢰적인 프로토콜이라고 부릅니다.
질문자님의 의도가 신뢰적인(reliable) UDP를 만드는 것이 필요하다는 얘기로 이해했습니다.
Stevens의 UNP를 보면 "reliable... UDP"라는 부분이 있는데,
여기서 그것을 구현하고 있습니다. UNP 1에서는 8장인가?이고,
UNP 2에서는 20.5입니다.
책에서 제공된 Stevens의 소스는 SAW ARQ를 사용하여, 구현한 것입니다. 보내고 응답받고 인데,...
타임아웃걸어서 응답안오면 또보내고 , 또 안오면 또보내고 ...입니다. 타임아웃은 전형적인...... 지수함수로 계산합니다.
그래서, 영원히 재전송은 아니고, 어느정도 시간동안 이상(?)하면, 실패로 간주합니다.(TCP도 그러하지요)

* 그런데, TCP조합이 아니고 UDP인가요? -.-a;

jika의 이미지

제가 지금 진행하고 있는 프로토콜은 GTP-U 라고 3GPP 에서 제시한 규약입니다.

물론 아래쪽은 udp/ip 이구요...

학교에서 통신 관련 정공을 하지 않은데다가 네트워크쪽 경험이 없어서

고생하던터 였습니다. 좋은 충고 감사합니다.

이젠 감을 잡았으니....

일하러...

진행하다가 또 의문있으면 글 올리겠습니다.

익명 사용자의 이미지

jika wrote:
제가 지금 진행하고 있는 프로토콜은 GTP-U 라고 3GPP 에서 제시한 규약입니다.
...

좋은 일 하고 계시군요.
저는 그냥 시키는 일, 하고 삽니다.
jika의 이미지

저도 시켜서 하는 일입니다 제가 학교에서 하던일하고도 좀 다르구요.. ㅜ_ㅜ;

지금 시퀀스가 있는 페킷들을 커널내부에서 reordering을 해야 하는데요.

일단 큐에 집어넣고 일정 갯수마다 혹은 일정 시간마다 큐안에

들어온 페킷들 순서를 정리해줘야 할듯 싶습니다.

문제는 일정 갯수가 될지 일정 시간이 될지 모르겠습니다만

표준문서에 별다른 언급이 없다는 겁니다.

결국에는 일정사이즈가 되면 리오더링하는걸로 하게 될듯한데..

일반적으로 이 사이즈를 어떻게 결정하는지 궁금합니다.

퍼포먼스에 영향을 많이 줄것 같은데요..

문서를 좀더 봐야겠지만 언급이 없으면 제 맘대로인데요..

보통 이런경우에 어떤점들을 고려해서 결정하는지 모르겠습니다.

익명 사용자의 이미지

일정개수라면 다다익선이고(메모리크기를 고려하여 패킷수를 적절한 값 선택)
일정시간도 길수록 좋지만,... 보통 세션/플로우기준으로 30초정도를 기본으로 합니다. 30초동안 뭔가 트래픽이 발생하지 않거나/TCP의 경우 FIN등으로 정상종료하면, 단절된 것으로 보겠다는 것이지요...

일단 세션/플로우들을 검색하기 용이한 자료구조가 있어야하며,(보통 IPS등에서는 BMT시 동시 100만~200만세션 이상을 요구하기도 한다는......)
각 세션/플로우별로 insert시 소팅되어 들어가는 자료구조가 있어야 하는데,
이둘은 복합자료구조형태로 있어야 할것입니다.
자료구조의 성능을 잘 고려해서 만드시고, 메모리를 고려해서 코딩하셔야 하겠습니다. 사실 이 자료구조 및 운영알고리즘이 이 부분의 꽃이겠지요.

* 일단 받아놓고 순서조정하는 것은 비실시간 응용에 적합합니다. 좀 늦어도 되고 모 그런 것들이겠지요. 이를테면, 세션도청/통계등 프로그램등이겠지요...

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.