[Develope]/Network

FD_SETSIZE 의 지정

하늘을닮은호수M 2011. 11. 24. 14:26
반응형

FD_SETSIZE 의 지정

Solaris 의 경우에는 시스템의 기본 FD_SETSIZE (대개 1024) 보다 큰 fd_set 을 사용하는 경우, (본 글에서는, 예로서 32767 로 지정하는 것으로 하겠습니다) 컴파일 파라메터로 -DFD_SETSIZE=32767 를 지정하기만 하면 되었는데요,

Linux 2.6 의 경우에는, FD_SETSIZE 를 지정하는 것이 모두 시스템 기본값인 1024 로 overwrite 되도록 시스템의 헤더가 구성되어 있어, 위와 같은 지정으로는 효과를 볼 수 없습니다. 아마도 Linux 2.4 등에서 가지고 있던 FD_SETSIZE 가 kernel compile 시에 고정되는 제약이 헤더 상에 남아 있는게 아닌가 싶습니다. (커널코드 확인결과 2.6에는 이러한 제약이 없습니다. 시험 결과로도 그렇구요) (bits/types.h 등에서 다시포함하는 linux/posix_types.h 내에서 __FD_SETSIZE를 undef 합니다)

따라서, Linux 2.6 에서 FD_SETSIZE 를 변경하여 사용하려면, 모든 #include 이전에 다음과 같은 꼼수의 cpp 명령을 지정하는 방법밖에 없습니다: (물론, runtime시 시스템 limit 값에서의 descriptors (기본 1024) 도 늘려야 하구요)

#include <bits/types.h>
#undef __FD_SETSIZE
#define __FD_SETSIZE  32768

fd_set 관련 매크로의 지정을 보면, FD_SETSIZE 값이 8 * sizeof(long int) 의 값 (즉, 64)의 배수가 되는 것을 가정하여 작성되어 있습니다. 따라서, 기존의 32767 대신 32768 을 사용하는 것이 맞습니다.

[편집]Linux 2.6 에서 FD_SET() macro의 안전성 문제

시험 결과, FD_SET() 매크로에서는 지정한 fd 값이 FD_SETSIZE 이내 인지에 대한 range check 를 수행하지 않음을 확인하였습니다.

따라서, 시스템의 descriptors limit (1024)를 늘리던가 해서 기본으로 가정된 FD_SETSIZE (1024)를 넘어선 fd 를 사용하는 경우, select()등을 위해 FD_SET() 매크로 수행시 메모리의 잘못된 부분을 건드리게 됩니다. 일반적인 top-down 방식의 stack 관리 구조에서는 segmentation fault 를 유발하지는 않지만 스택내 임의의 값이 수정되므로, 어떤 문제가 발생할지 예측할 수 없게 됩니다.

descriptors limit를 변경하여 1024개 이상의 많은 fd를 사용하는 경우 주의할 필요가 있습니다.

Invalid 한 fd 값으로 사용되는 -1값이 들어가면 어떨까요? 역시나 fd=-1 인 값이 들어가도 마찬가지로 아무런 체크가 없어 문제를 일으키게 되구요. 대충 살펴본 바로는 Solaris 쪽도 range check가 없는 건 마찬가지입니다.

반응형

'[Develope] > Network' 카테고리의 다른 글

ERRNO listing for Linux RH6.2, 2.2.19  (0) 2009.03.04
홀 펀칭(Hole Punching)  (1) 2008.08.11
TCP State Diagram  (0) 2008.07.28
posix proactor library test  (0) 2008.07.01
posix proactor library  (0) 2008.07.01