제임스딘딘의
Tech & Life

개발자의 기록 노트/C

[네트워크/C] addrinfo 구조체

제임스-딘딘 2017. 6. 16. 01:14

이 포스팅은 POSIX/리눅스에서 C 언어를 사용한 네트워크 소켓 프로그래밍과 관련된 글이다.


addrinfo 구조체는 네트워크 주소정보(인터넷 주소)와 호스트이름을 표현하는데 사용되며, 이 정보는 bind( ), connect( )호출 시 입력 파라미터에 사용될 수 있다.

또한 getaddrinfo( ) 함수 호출 시, hint 정보를 알리는 입력 파라미터로 사용할 수 있으며, getaddrinfo( ) 함수의 결과값을 전달하는 출력 파라미터로도 사용된다.


관련 헤더

struct addrinfo를 코드에서 사용하기 위해서는 아래 헤더파일을 포함시키면 된다.
#include <netdb.h>



구조체 원형

struct addrinfo {
   int          ai_flags;           /* 추가적인 옵션을 정의 할 때 사용함. 여러 flag를 bitwise OR-ing 하여 넣는다 */
   int          ai_family;          /* address family를 나타냄. AF_INET, AF_INET6, AF_UNSPEC */
   int          ai_socktype;        /* socket type을 나타냄. SOCK_SREAM, SOCK_DGRAM */
   int          ai_protocol;        /* IPv4와 IPv6에 대한 IPPROTO_xxx와 같은 값을 가짐. */
   socklen_t    ai_addrlen;         /* socket 주소인 ai_addr의 길이를 나타냄 */
   char        *ai_canonname;       /* 호스트의 canonical name을 나타냄 */
   struct sockaddr    *ai_addr;     /* socket 주소를 나타내는 구조체 포인터 */
   struct addrinfo    *ai_next;     /* 주소정보 구조체 addrinfo는 linked list이다. 다음 데이터의 포인터 */
};


ai_flags 값 목록

ai_flags에 가능한 플래그 값은 아래와 같다.


AI_PASSIVE

The caller will use the socket for a passive open.


AI_CANONNAME

Tells the function to return the canonical name of the host.


AI_NUMERICHOST

Prevents any kind of name-to-address mapping; the hostname argument must be an address string.


AI_NUMERICSERV

Prevents any kind of name-to-service mapping; the service argument must be a decimal port number string.


AI_V4MAPPED

If specified along with an ai_family of AF_INET6, then returns IPv4-mapped IPv6 addresses corresponding to A records if there are no available AAAA records.


AI_ALL

If specified along with AI_V4MAPPED, then returns IPv4-mapped IPv6 addresses in addition to any AAAA records belonging to the name.


AI_ADDRCONFIG

Only looks up addresses for a given IP version if there is one or more interface that is not a loopback interface configured with an IP address of that version.



ai_addrlen의 type관련 주의사항

어떤 운영체제에서는 socklen_t가 아닌 size_t를 ai_addrlen으로 사용하기도 한다.


대부분의 소켓함수에서 두 type은 호환되지만, 호환불가능한 경우 런타임 오류룰 발생시키는 경우가 있다. 

예를 들면, big-endian을 사용하는 64-bit Solaris 9 시스템은 size_t는 8바이트, socketlen_t는 4바이트 이므로 두 type간 호환되지 않고 런타임 오류 발생할 것이다.

따라서 본인이 작성한 코드가 어떤 시스템 위에서 동작할 지를 충분히 고려해야 한다.

같이보기

getaddrinfo 함수 - 2017/06/16 - [Software Dev Note/Embedded Linux] - [네트워크/C] getaddrinfo 함수