LWIP之DNS

  1. 先把宏定义添加上去

#ifndef LWIP_DNS
#define LWIP_DNS 1
#endif

  1. 在系统初始化调用
    dns_init();
    1、创建一个udp的专用于dns的dns_pcb控制块
    2、dns_setserver指定dns的服务器地址写进dns_servers数组

  2. 在while(1)之前或者在你认为需要调用的地方调用dns_gethostbyname(const char *hostname, ip_addr_t *addr, dns_found_callback found, void *found)

其中,hostname为你需要解析的域名,addr为解析返回的IP地址指针,found回调函数。
=>dns_enqueue将需要dns的域名填充存放在dns_table
这个table的大小就是同时可以dns的域名数量的多少了!
=>dns_check_entry检查dns_table的状态机
=>根据状态机调用dns_send向dns_servers发送数据

=>dns_tmr有个dns定时器不断的dns请求
=>dns_check_entries=>dns_check_entry

最后在dns_recv里收到域名对应的IP

4.特别注意:配置正确的DNS服务器地址。(尽量通过DHCP获取DNS服务器地址,不要手动填写)

/** DNS server IP address /
#ifndef DNS_SERVER_ADDRESS
#define DNS_SERVER_ADDRESS(ipaddr) (ip4_addr_set_u32(ipaddr, ipaddr_addr(“208.67.222.222”))) /
resolver1.opendns.com */
#endif

一般程序会将8.8.8.8设置为dns的服务器地址,这是Google提供的免费DNS服务器的IP地址

  1. 如果没有使用操作系统,需要自己添加定时处理函数,例如在LwIP_Periodic_Handle函数中添加:

#if LWIP_DNS
if (localtime - DNScoarseTimer >= DNS_TMR_INTERVAL)
{
DNScoarseTimer = localtime;
dns_tmr();
}
#endif

dns总结:
static struct dns_table_entry dns_table[DNS_TABLE_SIZE];
这个是用来存需要解析的域名的
DNS_TABLE_SIZE的大小限制域名的个数。

static ip_addr_t dns_servers[DNS_MAX_SERVERS];
DNS_MAX_SERVERS的大小限制了dns服务器地址的个数。

现在把dns_servers一分为二,一分是写死的dns地址,一分就是dhcp得到的dns地址。
将dns_servers大小改为4

#define DNS_MAX_SERVERS          4  // number of DNS servers, default 2

在dhcp_handle_ack函数中将得到的dns从dns_servers[2]开始写入,不然会被后面的手动写入覆盖调。
#if LWIP_DNS
  /* DNS servers */
  for(n = 0; (n < DNS_MAX_SERVERS-2) && dhcp_option_given(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n); n++) {
    ip_addr_t dns_addr;
    ip4_addr_set_u32(&dns_addr, htonl(dhcp_get_option_value(dhcp, DHCP_OPTION_IDX_DNS_SERVER + n)));
    LWIP_DEBUGF(DHCP_DEBUG | LWIP_DBG_ON, ("dhcp_bind(): DNS: 0x%08"X32_F"\n", ip4_addr_get_u32(&dns_addr)));
    dns_setserver(n, &dns_addr);
  }
#endif /* LWIP_DNS */

在dns_check_entry函数中,对每个dns server都重复DNS_MAX_RETRIES次数然后切换下一个dns server
if (++pEntry->retries == DNS_MAX_RETRIES)

 case DNS_STATE_ASKING: {
      if (--pEntry->tmr == 0) {
        **if (++pEntry->retries == DNS_MAX_RETRIES)** {
          if ((pEntry->numdns+1<DNS_MAX_SERVERS) && !ip_addr_isany(&dns_servers[pEntry->numdns+1])) {
            /* change of server */
            pEntry->numdns++;
            pEntry->tmr     = 1;
            pEntry->retries = 0;
            break;
          } else {
            LWIP_DEBUGF(DNS_DEBUG, ("dns_check_entry: \"%s\": timeout\n", pEntry->name));
            /* call specified callback function if provided */
            if (pEntry->found)
              (*pEntry->found)(pEntry->name, NULL, pEntry->arg);
            /* flush this entry */
            pEntry->state   = DNS_STATE_UNUSED;
            pEntry->found   = NULL;
            break;
          }
        }

dhcp_start是DHCP的流程操作的启动开始,与DNS一样都是udp方式的
dhcp_bind提供获得的IP地址,从dhcp_recv函数调用过来的
1.DHCPDISCOVER
2.DHCPOFFER
3.DHCPREQUEST
4.DHCPACK

可以通过dhcp_handle_ack来获取dns服务器地址,而不用手动设置

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值