trafficserver的DNS初始化源码分析二

来源:互联网 发布:淘宝显示多少人付款 编辑:程序博客网 时间:2024/05/04 02:27
原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。http://chenpiaoping.blog.51cto.com/5631143/1364488

DNSserver表的创建就是new一个DNS_table,跟踪到ControlMatcher的构造函数

main()--->DNSProcessor::start()--->SplitDNSConfig::reconfigure()--->ControlMatcher<Data,Result>::ControlMatcher()

template<classData,classResult>

ControlMatcher<Data,Result>::ControlMatcher(constchar*file_var,constchar*name,constmatcher_tags* tags,

intflags_in)

{

char*config_file = NULL;

flags= flags_in;

ink_assert(flags& (ALLOW_HOST_TABLE| ALLOW_REGEX_TABLE | ALLOW_URL_TABLE | ALLOW_IP_TABLE));

config_tags= tags;

ink_assert(config_tags!= NULL);

matcher_name= name;

config_file_var= ats_strdup(file_var);

config_file_path[0]='\0';

//读取配置项proxy.config.dns.splitdns.filename的值,即文件splitdns.config

REC_ReadConfigStringAlloc(config_file,config_file_var);

//参数flags_in用来控制是否要创建DNSserver表,如果不许要创建则啥也不做了

if(!(flags &DONT_BUILD_TABLE)) {

ink_release_assert(config_file !=NULL);

ink_filepath_make(config_file_path,sizeof(config_file_path),system_config_directory, config_file);

}

ats_free(config_file);

reMatch= NULL;

urlMatch= NULL;

hostMatch= NULL;

ipMatch= NULL;

hrMatch= NULL;

if(!(flags &DONT_BUILD_TABLE)) {

//创建DNSserver

m_numEntries=this->BuildTable();

}else{

m_numEntries= 0;

}

}

//创建DNSserver

main()--->DNSProcessor::start()--->SplitDNSConfig::reconfigure()--->ControlMatcher<Data,Result>::ControlMatcher()--->template<classData,classResult>intControlMatcher<Data, Result>::BuildTable

template<classData,classResult>intControlMatcher<Data,Result>::BuildTable()

{

//File I/O Locals

char*file_buf;

intret;

//先把splitdns.config的内容读到file_buf

file_buf =readIntoBuffer(config_file_path,matcher_name,NULL);

if(file_buf == NULL) {

return1;

}

//再根据file_buf创建DNSserver

ret= BuildTableFromString(file_buf);

ats_free(file_buf);

returnret;

}

//继续创建DNSserver

main()--->DNSProcessor::start()--->SplitDNSConfig::reconfigure()--->ControlMatcher<Data,Result>::ControlMatcher()--->template<classData,classResult>intControlMatcher<Data, Result>::BuildTableFromString()

template<classData,classResult>intControlMatcher<Data,Result>::BuildTableFromString(char*file_buf)

{

TokenizerbufTok("\n");

tok_iter_statei_state;

constchar*tmp;

matcher_line*first = NULL;

matcher_line*current;

matcher_line*last = NULL;

intline_num = 0;

intsecond_pass = 0;

intnumEntries = 0;

boolalarmAlready =false;

charerrBuf[1024];

constchar*errPtr = NULL;

inthostDomain = 0;

intregex = 0;

inturl = 0;

intip = 0;

inthostregex = 0;

if(bufTok.Initialize(file_buf, SHARE_TOKS | ALLOW_EMPTY_TOKS) == 0) {

return0;

}

tmp= bufTok.iterFirst(&i_state);

//循环处理每一行

while(tmp != NULL) {

line_num++;

//去掉空字符

while(*tmp &&isspace(*tmp)){

tmp++;

}

if(*tmp !='#'&& *tmp != '\0'){

current = (matcher_line*)ats_malloc(sizeof(matcher_line));

//解析一行,并把解析的结果放到current

errPtr = parseConfigLine((char*) tmp, current,config_tags);

//如果解析出错则释放current

if(errPtr != NULL) {

if(config_tags!= &socks_server_tags) {

snprintf(errBuf,sizeof(errBuf),"%s discarding %s entry at line %d: %s",

matcher_name,config_file_path,line_num, errPtr);

SignalError(errBuf,alarmAlready);

}

ats_free(current);

} else{

//解析的行数++

numEntries++;

//当前行数

current->line_num= line_num;

//根据解析得到每行的类型,根据类型进行相应的计数

switch(current->type){

caseMATCH_HOST:

caseMATCH_DOMAIN:

hostDomain++;

break;

caseMATCH_IP:

ip++;

break;

caseMATCH_REGEX:

regex++;

break;

caseMATCH_URL:

url++;

break;

caseMATCH_HOST_REGEX:

hostregex++;

break;

caseMATCH_NONE:

default:

ink_assert(0);

}

//把所有解析好的行拉成队列

if(first == NULL) {

ink_assert(last == NULL);

first = last = current;

} else{

last->next= current;

last = current;

}

}

}

tmp = bufTok.iterNext(&i_state);

}

//如果解析完成后没有一行是正确的,则直接返回

if(numEntries == 0) {

ats_free(first);

return0;

}

//根据控制标志flags和解析结果按照分类创建相应Matcher,分为reMatch(正则表达式)、urlMatchurl)、hostMatch(主机名)、ipMatchip地址)、hrMatch(主机名正则表达式)

if((flags &ALLOW_REGEX_TABLE) && regex > 0) {

reMatch= NEW((newRegexMatcher<Data,Result>(matcher_name,config_file_path)));

reMatch->AllocateSpace(regex);

}

if((flags &ALLOW_URL_TABLE) && url > 0) {

urlMatch= NEW((newUrlMatcher<Data,Result>(matcher_name,config_file_path)));

urlMatch->AllocateSpace(url);

}

if((flags &ALLOW_HOST_TABLE) && hostDomain > 0) {

hostMatch= NEW((newHostMatcher<Data,Result>(matcher_name,config_file_path)));

hostMatch->AllocateSpace(hostDomain);

}

if((flags &ALLOW_IP_TABLE) && ip > 0) {

ipMatch= NEW((newIpMatcher<Data,Result>(matcher_name,config_file_path)));

ipMatch->AllocateSpace(ip);

}

if((flags &ALLOW_HOST_REGEX_TABLE) && hostregex > 0) {

hrMatch= NEW((newHostRegexMatcher<Data,Result>(matcher_name,config_file_path)));

hrMatch->AllocateSpace(hostregex);

}

//把解析好的队列里的matcher_line根据类型加到对应的Matcher

current = first;

while(current != NULL) {

second_pass++;

if((flags &ALLOW_HOST_TABLE) && current->type==MATCH_DOMAIN){

errPtr =hostMatch->NewEntry(current);

}elseif((flags &ALLOW_HOST_TABLE) && current->type== MATCH_HOST){

errPtr =hostMatch->NewEntry(current);

}elseif((flags &ALLOW_REGEX_TABLE) && current->type== MATCH_REGEX){

errPtr =reMatch->NewEntry(current);

}elseif((flags &ALLOW_URL_TABLE) && current->type== MATCH_URL){

errPtr =urlMatch->NewEntry(current);

}elseif((flags &ALLOW_IP_TABLE) && current->type==MATCH_IP){

errPtr =ipMatch->NewEntry(current);

}elseif((flags &ALLOW_HOST_REGEX_TABLE) && current->type== MATCH_HOST_REGEX){

errPtr =hrMatch->NewEntry(current);

}else{

errPtr = NULL;

snprintf(errBuf,sizeof(errBuf),"%s discarding %s entry withunknown type at line %d",

matcher_name,config_file_path,current->line_num);

SignalError(errBuf,alarmAlready);

}

if(errPtr != NULL) {

SignalError(errPtr,alarmAlready);

errPtr = NULL;

}

last = current;

current = current->next;

ats_free(last);

}

ink_assert(second_pass ==numEntries);


if(is_debug_tag_set("matcher")){

Print();

}

returnnumEntries;

}

到这就行了,再细的自己看看就OK了,回去再往下看,上面是splitDNS的初始化,下面该DNS的初始化了,该函数的功能是根据配置的把所有DNSserver找出来放到DNSProcessorl_res

main()--->DNSProcessor::start()--->DNSProcessor::dns_init()

void

DNSProcessor::dns_init()

{

gethostname(try_server_names[0],255);

Debug("dns","localhost=%s\n",try_server_names[0]);

Debug("dns","Round-robinnameservers= %d\n", dns_ns_rr);

IpEndpointnameserver[MAX_NAMED];

size_tnserv = 0;

//dns_ns_listDNSserver列表,读取配置项proxy.config.dns.nameservers而来的

if(dns_ns_list) {

Debug("dns","Nameserverlist specified \"%s\"\n",dns_ns_list);

inti;

char*last;

char*ns_list = ats_strdup(dns_ns_list);

char*ns = (char*)strtok_r(ns_list," ,;\t\r",&last);

//追个解析配置的DNSserver

for(i = 0, nserv = 0 ; (i < MAX_NAMED) && ns ; ++i) {

Debug("dns","Nameserverlist - parsing \"%s\"\n",ns);

boolerr =false;

intprt = DOMAIN_SERVICE_PORT;

char*colon = 0;

//如果有端口的话取出来

if('[' ==*ns) {

char*ndx =strchr(ns+1,']');

if(ndx) {

if(':' ==ndx[1]) colon = ndx+1;

} else{

err = true;

Warning("Unmatched'[' in address fornameserver'%s', discarding.", ns);

}

} elsecolon = strchr(ns,':');

if(!err && colon) {

*colon = '\0';

if(sscanf(colon+ 1,"%d%*s",&prt) != 1) {

Debug("dns","Unable to parse port number '%s'for nameserver'%s',discardin.",colon + 1, ns);

Warning("Unableto parse port number '%s' fornameserver'%s', discarding.", colon + 1, ns);

err = true;

}

}

if(!err && 0 != ats_ip_pton(ns, &nameserver[nserv].sa)){

Debug("dns","Invalid IP address given fornameserver'%s', discarding", ns);

Warning("InvalidIP address given fornameserver'%s', discarding", ns);

err = true;

}

//ip地址和端口放到数组nameserver

if(!err) {

ip_port_text_bufferbuff;

ats_ip_port_cast(&nameserver[nserv].sa)=htons(prt);

Debug("dns","Addingnameserver%s tonameserverlist",

ats_ip_nptop(&nameserver[nserv].sa,buff,sizeof(buff))

);

++nserv;

}

ns = (char*)strtok_r(NULL," ,;\t\r",&last);

}

ats_free(ns_list);

}

//下面从resolv.conf中读取信息了,dns_resolv_conf的值为读取配置项proxy.config.dns.resolv_conf而来,即resolv.conf,解析resolv.conf后把DNSserver放到数组nameserver中,最后拷贝到l_resnsaddr_list中,顺便初始化该变量

if(ink_res_init(&l_res,nameserver, nserv, NULL, NULL, dns_resolv_conf) < 0)

Warning("Failedto build DNS res records for the servers (%s).  Using resolv.conf.",dns_ns_list);

if(dns_local_ipv6) {

if(0 != ats_ip_pton(dns_local_ipv6, &local_ipv6)){

ats_ip_invalidate(&local_ipv6);

Warning("InvalidIP address '%s' for dns.local_ipv6 value, discarding.",dns_local_ipv6);

}elseif(!ats_is_ip6(&local_ipv6.sa)){

ats_ip_invalidate(&local_ipv6);

Warning("IPaddress '%s' for dns.local_ipv6 value was not IPv6, discarding.",dns_local_ipv6);

}

}

if(dns_local_ipv4) {

if(0 != ats_ip_pton(dns_local_ipv4, &local_ipv4)){

ats_ip_invalidate(&local_ipv4);

Warning("InvalidIP address '%s' for dns.local_ipv4 value, discarding.",dns_local_ipv4);

}elseif(!ats_is_ip4(&local_ipv4.sa)){

ats_ip_invalidate(&local_ipv4);

Warning("IPaddress '%s' for dns.local_ipv4 value was not IPv4, discarding.",dns_local_ipv4);

}

}

}

启动DNS

main()--->DNSProcessor::start()--->DNSProcessor::open()

void

DNSProcessor::open(sockaddrconst*target,intaoptions)

{

//创建并初始化DNSHandler

DNSHandler*h = NEW(newDNSHandler);

h->options= aoptions;

h->mutex=thread->mutex;

//引用DNSserver

h->m_res= &l_res;

ats_ip_copy(&h->local_ipv4.sa,&local_ipv4.sa);

ats_ip_copy(&h->local_ipv6.sa,&local_ipv6.sa);

if(target)

ats_ip_copy(&h->ip,target);

else

ats_ip_invalidate(&h->ip);

//handler指向DNSHandler实例

if(!dns_handler_initialized)

handler= h;

//设置DNSHandlerhandlerDNSHandler::startEvent,并立马调度执行DNSHandler::startEvent

SET_CONTINUATION_HANDLER(h,&DNSHandler::startEvent);

thread->schedule_imm(h);

}


本文出自 “陈漂评的博客” 博客,请务必保留此出处http://chenpiaoping.blog.51cto.com/5631143/1364488

0 0
原创粉丝点击