getaddrinfo工做原理分析

getaddrinfo工做原理分析

將域名解析成ip地址是全部涉及網絡通信功能程序的基本步驟之一,經常使用的兩個接口是gethostbyname和getaddrinfo,然後者是Posix標準推薦在新應用中使用的接口。很好奇,getaddrinfo的工做原理,接下來就簡要分析getaddrinfo函數的工做過程。服務器

函數原型

#include<netdb.h>
int getaddrinfo( const char *hostname, const char *service, const struct addrinfo *hints, struct addrinfo **result );
//返回值:成功 返回 0;錯誤 返回非零錯誤碼

參數

  • hostname:一個主機名或者地址串(IPv4的點分十進制串或者IPv6的16進制串)
  • service:服務名能夠是十進制的端口號,也能夠是已定義的服務名稱,如ftp、http等
  • hints: hints是一個模板,它只使用ai_family,ai_flags,以及ai_socktype成員,用來過濾地址。剩下的整數成員必須被設置成0.
  • result:本函數經過result指針參數返回一個指向addrinfo結構體鏈表的指針。
    addrinfo 結構
struct addrinfo {
  int               ai_flags;       /* customize behavior */
  int               ai_family;      /* address family */
  int               ai_socktype;    /* socket type */
  int               ai_protocol;    /* protocol */
  socklen_t         ai_addrlen;     /* length in bytes of address */
  struct sockaddr  *ai_addr;        /* address */
  char             *ai_canonname;   /* canonical name of host */
  struct addrinfo  *ai_next;        /* next in list */
  .
 };

功能分析

Flag Description
AI_ADDRCONFIG 請求配置的是哪一種地址類型(IPv4或者IPv6)。
AI_ALL 對IPv4和IPv6地址都進行查找(只和AI_V$MAPPED一塊使用)。
AI_CANONNAME 請求一個正式的名稱(和別名相對)。
AI_NUMERICHOST 以數字形式返回主機地址。
AI_NUMERICSERV 將服務做爲端口號碼返回。
AI_PASSIVE 綁定套接字地址以便偵聽。
AI_V4MAPPED 若是沒有發現IPv6地址,那麼返回以IPv6格式映射的IPv4地址。

實例分析過程

要想知道getaddrinfo是如何查詢信息的,能夠用strace工具,追蹤getaddrinfo函數 在執行時打開了哪些文件。
利用APUE 第三版 圖16-9的程序,來分析網絡

$ gcc 16-9.c -o getaddr
$ strace -e trace=file -o file ./getaddr google.com http
$ cat file

截取file中與本次目的相關輸出socket

open("/etc/nsswitch.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/services", O_RDONLY|O_CLOEXEC) = 3
open("/etc/host.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/resolv.conf", O_RDONLY|O_CLOEXEC) = 3
open("/etc/hosts", O_RDONLY|O_CLOEXEC) = 3函數

如今來逐個分析這些文件工具

/etc/services

該文件是記錄網絡服務名和它們對應使用的端口號及協議。google

/etc/host.conf

該文件指定如何解析主機名,cat /etc/host.conf指針

# The "order" line is only used by old versions of the C library.
order hosts,bind
multi on

「order hosts,bind」指定主機名查詢順序,這裏規定先查詢「/etc/hosts」文件,而後再使用DNS來解析域名(也能夠相反)。
「multi on」指定是否「/etc/hosts」文件中指定的主機能夠有多個地址,擁有多個IP地址的主機通常稱爲多穴主機。
其中BIND是一種開源的DNS(Domain Name System)協議的實現,包含對域名的查詢和響應所需的全部軟件。它是互聯網上最普遍使用的一種DNS服務器,對於類UNIX系統來講,已經成爲事實上的標準。code

/etc/hosts

保存主機名和IP配置文件,Linux 的/etc/hosts是配置ip地址和其對應主機名的文件,這裏能夠記錄本機的或其餘主機的ip及其對應主機名dns

/etc/resolv.conf

文件功能:DNS客戶機配置文件,設置DNS服務器的IP地址及DNS域名接口

/etc/nsswitch.conf

文件/etc/nsswitch.conf(name service switch configuration,名字服務切換配置)規定經過哪些途徑以及按照什麼順序經過這些途徑來查找特定類型的信息。還能夠指定若某個方法奏效抑或失效系統將採起什麼動做。
cat /etc/nsswitch.conf ,截取 hosts一項
hosts: files mdns4_minimal [NOTFOUND=return] dns mdns4

  • files 表示解析位於 /etc/hosts文件中的靜態主機名。
  • mdns4_minimal 試圖用組播DNS ( Multicast DNS)來解析名字。
  • [NOTFOUND=return] 意思是mdns4_minimal沒有找到就再也不繼續了.
  • dns 表明傳統的單播DNS (unicast DNS)查詢 .
  • mdns4 表明一個多播DNS查詢

結論(我的見解,若有錯誤,歡迎指正)

1.讀取/etc/nsswitch.conf,如果先讀hosts文件,則根據名字在hosts文件中查找,若找到,則返回,若找不到,則使用DNS Bind客戶端進行域名解析處理 2.讀取/etc/services,查詢通用服務名與端口號對應關係。 3.讀取/etc/host.conf 該配置文件爲域名解析順序配置文件,設定解析順序方式 4.讀取/etc/resolv.conf配置文件,該文件用於指定解析的DNS服務器,以及DNS Bind解析時的相關參數,如重試次數,超時時間等 5.讀取/etc/hosts 文件,查找主機名查詢靜態表 6.hosts文件未找到主機名時,使用DNS Bind客戶端進行域名解析時,會採用/etc/resolv.conf配置文件進行域名解析,解析的方式由resolve.conf文件決定

相關文章
相關標籤/搜索