Domain Name
: 서버는 IP주소로 구분되나, 이를 기억하고 사용하기는 어려우므로 IP주소에 이름을 부여한 것
도메인 이름을 컴퓨터가 이해할 수 있는 IP 주소로 변환해주는 서버.
DNS 서버가 모든 도메인을 알고 있는 것은 아니여서, DNS 서버가 모르는 경우에는 다른 DNS 서버로 통신하여 해당 도메인에 대한 정보를 알아온다고 한다.
계속해서 도메인에 대한 정보를 찾아 거슬러 올라가다보면, 최상위 DNS서버(Root DNS)가 나온다. 루트 서버는 어디로 도메인을 질문해야하는지를 알고있어서, 해당 도메인을 알고있는 DNS로 질문을 던진다고 한다.
-> 일종의 분산 데이터베이스 시스템.
그렇다면 도메인 이름을 이용해서 IP주소를 얻기위해선 어떻게 해야할까?
아래의 함수를 이용하면, 해당 도메인 주소가 가리키고 있는 IP주소를 알 수 있게 된다.
#include <netdb.h>
struct hostent * gethostbyname(const char * hostname);
함수의 인자로 도메인 명을 넘기게 되면, 해당 도메인을 사용하는 IP주소정보를 얻을 수 있다.
단, hostent
라는 구조체 변수에 담겨 나오게 된다.
struct hostent
{
char * h_name; // 공식 도메인 이름
char ** h_aliases; // 공식 도메인의 별명. (ex: facebook -> fb)
int h_addrtype; // IP주소의 주소체계 정보(IPv4, IPv6 등)
int h_length; // 함수 호출 결과로 반환된 IP주소의 크기 정보(IPv4 -> 4바이트 / IPv6 : 16 바이트)
char ** h_addr_list; // 도메인에 해당하는 모든 IP주소정보를 정수 형태로 반환.
}
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netdb.h>
int main(int argc, char **argv)
{
int i;
struct hostent *host;
host = gethostbyname(argv[1]);
if (!host)
{
return 1;
}
printf("official name: %s \n", host->h_name);
for (i = 0; host->h_aliases[i]; i++)
printf("Aliases %d: %s \n", i + 1, host->h_aliases[i]);
printf("Address type: %s \n",
(host->h_addrtype==AF_INET) ? "AF_INET" : "AF_INET6");
for (i = 0; host->h_addr_list[i]; i++)
printf("IP addr %d: %s \n", i+1,
inet_ntoa(*(struct in_addr*)host->h_addr_list[i]));
return 0;
}
간단한 테스트 코드를 돌려서 도메인에 대해 얻어지는 정보를 확인해보았다.
sihkang in /goinfre/sihkang λ ./a.out www.pearlabyss.com
official name: mhnq5r2.impervadns.net
Aliases 1: www.pearlabyss.com
Address type: AF_INET
IP addr 1: 45.223.21.187
./a.out www.google.com
official name: www.google.com
Address type: AF_INET
IP addr 1: 142.250.207.100
./a.out www.x.com
official name: x.com
Aliases 1: www.x.com
Address type: AF_INET
IP addr 1: 104.244.42.193
IP addr 2: 104.244.42.65
IP addr 3: 104.244.42.129
IP addr 4: 104.244.42.1
내가 최근 즐겨하는 검은사막의 개발사인 펄어비스, 그리고 구글, 트위터를 확인했다.
처음에 펄어비스를 확인했을때는 IP주소가 하나여서, 게임사 홈페이지는 상대적으로 트래픽이 적어서 하나의 서버만 사용하나 싶었는데, 의외로 구글의 도메인에서도 하나의 서버IP만 나왔다. 트위터는 4개나 나왔는데 이게 접속자수가 많은 도메인의 경우 여러 서버를 두어 부하를 분산한다고 알고있는데 어째서 구글은 단 하나로 처리를 하고 있는건지 궁금하다.
일반적으로 gethostbyname 함수는 도메인 이름을 IP 주소로 변환하는 기능을 제공합니다. 하지만 이는 실제 서버 구성과 부하 분산 기술을 완전히 반영하지 않습니다.
구글과 같은 대규모 서비스 업체는 다음과 같은 기술을 사용하여 실제 서버 구성을 숨기고 있습니다:
따라서 gethostbyname 함수로 확인되는 IP 주소는 실제 서버 구성의 일부분만을 보여줄 뿐이며, 보다 정확한 정보를 얻기 위해서는 추가적인 분석이 필요.
역으로 gethostbyaddr()
을 이용하도록 하자.
#include <netdb.h>
struct hostnet * gethostbyaddr(const char * addr, socklen_t len, int family);
해당 챕터에서는 도메인과 IP주소의 관계, 그리고 그 관계를 확인할 수 있는 함수(gethostbyname, gethostbyaddr) 에 대해 배웠다. 해당 도메인이 어떤 서버IP로 이어지는지를 볼 수 있었으나, 그 이면에는 더 깊은 내용들(로드밸런서, 프록시서버, CDN 등)이 존재하고 있었다.