您的位置:首页 > 其它

trafficserver的DNS初始化源码分析二

2014-04-02 23:09 274 查看
原创作品,允许转载,转载时请务必以超链接形式标明文章
原始出处 、作者信息和本声明。否则将追究法律责任。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(正则表达式)、urlMatch(url)、hostMatch(主机名)、ipMatch(ip地址)、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找出来放到DNSProcessor的l_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-robin
nameservers= %d\n", dns_ns_rr);
IpEndpointnameserver[MAX_NAMED];
size_tnserv = 0;
//dns_ns_list是DNSserver列表,读取配置项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 for
nameserver'%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' for
nameserver'%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 for
nameserver'%s', discarding", ns);
err =
true;
}
//把ip地址和端口放到数组nameserver中
if(!err) {
ip_port_text_bufferbuff;
ats_ip_port_cast(&nameserver[nserv].sa)=
htons(prt);
Debug("dns","Adding
nameserver%s to
nameserverlist",
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_res的nsaddr_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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: