| 353 | | } |
| 354 | | |
| 355 | | |
| 356 | | /** returns 1 in case of a straight match, 2 in case of a wildcard CNAME (groan), 0 in case of no hit */ |
| 357 | | int PacketHandler::doWildcardRecords(DNSPacket *p, DNSPacket *r, string &target) |
| 358 | | { |
| 359 | | DNSResourceRecord rr; |
| 360 | | bool found=false, retargeted=false; |
| 361 | | |
| 362 | | // try chopping off domains and look for wildcard matches |
| 363 | | |
| 364 | | // *.pietje.nl IN A 1.2.3.4 |
| 365 | | // pietje.nl should now NOT match, but www.pietje.nl should |
| 366 | | |
| 367 | | string subdomain=target; |
| 368 | | string::size_type pos; |
| 369 | | |
| 370 | | while((pos=subdomain.find("."))!=string::npos) { |
| 371 | | subdomain=subdomain.substr(pos+1); |
| 372 | | // DLOG(); |
| 373 | | |
| 374 | | string searchstr=string("*.")+subdomain; |
| 375 | | |
| 376 | | B.lookup(QType(QType::ANY), searchstr,p); // start our search at the backend |
| 377 | | |
| 378 | | while(B.get(rr)) { // read results |
| 379 | | if(retargeted) |
| 380 | | continue; |
| 381 | | found=true; |
| 382 | | if((p->qtype.getCode()==QType::ANY || rr.qtype==p->qtype) || rr.qtype.getCode()==QType::CNAME) { |
| 383 | | rr.qname=target; |
| 384 | | |
| 385 | | if(d_doFancyRecords && p->qtype.getCode()==QType::ANY && (rr.qtype.getCode()==QType::URL || rr.qtype.getCode()==QType::CURL)) { |
| 386 | | rr.content=::arg()["urlredirector"]; |
| 387 | | rr.qtype=QType::A; |
| 388 | | } |
| 389 | | |
| 390 | | r->addRecord(rr); // and add |
| 391 | | if(rr.qtype.getCode()==QType::CNAME) { |
| 392 | | if(target==rr.content) { |
| 393 | | L<<Logger::Error<<"Ignoring wildcard CNAME '"<<rr.qname<<"' pointing at itself"<<endl; |
| 394 | | r->setRcode(RCode::ServFail); |
| 395 | | continue; |
| 396 | | } |
| 397 | | |
| 398 | | DLOG(L<<Logger::Error<<"Retargeting because of wildcard cname, from "<<target<<" to "<<rr.content<<endl); |
| 399 | | |
| 400 | | target=rr.content; // retarget |
| 401 | | retargeted=true; |
| 402 | | } |
| 403 | | } |
| 404 | | else if(d_doFancyRecords && ::arg().mustDo("wildcard-url") && p->qtype.getCode()==QType::A && rr.qtype.getName()=="URL") { |
| 405 | | rr.content=::arg()["urlredirector"]; |
| 406 | | rr.qtype=QType::A; |
| 407 | | rr.qname=target; |
| 408 | | |
| 409 | | r->addRecord(rr); |
| 410 | | } |
| 411 | | } |
| 412 | | if(found) { |
| 413 | | DLOG(L<<"Wildcard match on '"<<string("*.")+subdomain<<"'"<<", retargeted="<<retargeted<<endl); |
| 414 | | return retargeted ? 2 : 1; |
| 415 | | } |
| 416 | | } |
| 417 | | DLOG(L<<"Returning no hit for '"<<string("*.")+subdomain<<"'"<<endl); |
| 418 | | return 0; |