Chromium是如何实现DNS的解析

DNS解析是一种非常常见的解析方式,来看一下百度百科的说明:

DNS(Domain Name System,域名系统),因特网上作为域名和IP地址相互映射的一个分布式数据库,能够使用户更方便的访问互联网,而不用去记住能够被机器直接读取的IP数串。通过主机名,最终得到该主机名对应的IP地址的过程叫做域名解析(或主机名解析)。DNS协议运行在UDP协议之上,使用端口号53。在RFC文档中RFC 2181对DNS有规范说明,RFC 2136对DNS的动态更新进行说明,RFC 2308对DNS查询的反向缓存进行说明。

简单点说就是我们想登陆某一个网页,只需要记住有主观意义的域名,比如说www.bytedance.com, www.baidu.com, www.sina.cn 等等,甚至可以简单地把dns理解为一个key-value的分布式数据库,其中key值就是域名,而value就是域名对应的ip地址,这里并不是一一对应的关系,一个域名可以对应多个ip地址,这样做是为了防止当一个ip地址不可用时,可以切换到另一个ip地址,从而不会影响用户的业务。

关于dns的原理我们就简单介绍到这里,今天我们要讲的是chromium是如何实现dns解析的。大家可能对chromiun有点陌生,但我相信很多人一定都用过chrome浏览器,实际上chromiun就是chrome的项目源码名称,可不要小瞧chrome浏览器,其复杂程度不亚于一个操作系统,甚至你可以直接把chrome浏览器看成一个web操作系统,关于这个项目有很多值得学习的地方,比如说它的多进程调度,渲染器的使用,浏览器加速算法等等,在这里我们只关注它对于网络部分的实现.

Chromium中关于网络方面的实现均在net库中,实现了包括dns、http、udp、ftp、quic等等大家熟知的协议,大家感兴趣的话可以去网上下载chromium的源代码。

dns的代码路径是 src/net/dns, 通过下图可以看到文件有很多个,如果一个个点进去看,既浪费时间又很难真正理解dns的精髓。

下面我就带大家看一看chrome对于dns解析的实现:

第一步首先关注核心函数,这里的核心函数是指dns整个模块对外的一个接口,简单点说就是当用户在浏览器中输入网址时,主进程便会调用dns模块中的这个文件来获取相应的ip地址,而这里的核心函数就位于 host_resolver_impl.cc 中,其核心函数为:

int HostResolverImpl::Resolve(const RequestInfo& info,

RequestPriority priority,

AddressList* addresses,

const CompletionCallback& callback,

RequestHandle* out_req,

const BoundNetLog& source_net_log) ;

Key key = GetEffectiveKeyForRequest(info, source_net_log);

这里的key值时根据info得出的一组可以唯一标志dns中一种主机解析job,关于job的概念等会就会提到。

int rv = ResolveHelper(key, info, addresses, source_net_log);

可以看到在这里又新引入了一个ResolveHelper函数,这个函数的作用时根据计算得到的key值以及info值,依次判断是否为ip,能否从cache中得到,能否从host中得到,这个函数可以理解为一个辅助的解析函数。

JobMap::iterator jobit = jobs_.find(key);

Job* job;

加入辅助解析函数并未找到需要的ip地址,并且之前未启动相同的job(这里通过find函数来查找指定key值的job是否存在),则需要启动一个job来进行相应的dns解析,关于dns解析,这里有两种方式:

一种是要提到一个函数getaddrinfo(), 这个函数可以根据域名得到相应的ip地址,并且既可以用在ipv4上,也可以用在ipv6上,但由于其是一个系统级别的调用,因此是一个阻塞调用,chrome将这种方式称之为ProcTask方式:

而另外一种调用方式则是chromium按照dns协议规范,通过异步非阻塞的调用方式,实现了getaddrinfo()函数,这种方式被称之为DnsTask。

那究竟如何选择使用哪种方式来进行dns解析呢?还是要看代码,下面这些代码时job类中start()方法的实现:

void Start() override {

DCHECK_LE(num_occupied_job_slots_, 1u);

// Caution: Job::Start must not complete synchronously.

if (!system_only && had_dns_config_ &&

!ResemblesMulticastDNSName(key_.hostname)) {

StartDnsTask(); //满足上述条件后才使用DnsTask

} else {

StartProcTask(); //其余情况均使用ProcTask

}

}

当满足系统未指定解析方式、dns已经配置完成主机名满足一定条件才可以使用DnsTask,其余情况均使用ProcTask。

先来说一下ProcTask,这种方式较为简单,其最终回调用到函数SystemHostResolverCall() 中去, 而这个函数只是对 getaddrinfo() 做了一层封装而已,逻辑相对简单一些,感兴趣的同学可以去看一下源码,位置是在host_resolver.cc这个文件里。

DnsTask相对来说就复杂一些,简单点说就是通过调用StartA(),紧接着再调用

dns_query.cc、dns_transaction.cc,同时调用udp协议获取fd,然后将这个fd注册到网络库的io线程事件循环中,从而使得dns解析流程统一写到了异步回调的编程框架中。

好了,关于chromium中dns的解析暂时先说到这里,后续如果有更进一步的解析,我会及时更新并分享出来的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,284评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,115评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,614评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,671评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,699评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,562评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,309评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,223评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,668评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,859评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,981评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,705评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,310评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,904评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,023评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,146评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,933评论 2 355

推荐阅读更多精彩内容