| 550 | } |
| 551 | |
| 552 | struct hostent * own_gethostbyaddr(void *addr, socklen_t len, int af) |
| 553 | { |
| 554 | const unsigned char *uaddr = (const u_char *)addr; |
| 555 | static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff }; |
| 556 | static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 }; |
| 557 | int n; |
| 558 | int ret; |
| 559 | static union dns_query ptr_buff; |
| 560 | socklen_t size; |
| 561 | char qbuf[DNS_MAX_NAME+1]; |
| 562 | char *qp=NULL; |
| 563 | int min_ttl=INT_MAX; |
| 564 | struct hostent *cached_he; |
| 565 | |
| 566 | if (af == AF_INET6 && len == 16 && |
| 567 | (!memcmp(uaddr, mapped, sizeof mapped) || |
| 568 | !memcmp(uaddr, tunnelled, sizeof tunnelled))) { |
| 569 | /* Unmap. */ |
| 570 | addr += sizeof mapped; |
| 571 | uaddr += sizeof mapped; |
| 572 | af = AF_INET; |
| 573 | len = 4; |
| 574 | } |
| 575 | |
| 576 | switch (af) { |
| 577 | case AF_INET: |
| 578 | size = 4; |
| 579 | break; |
| 580 | case AF_INET6: |
| 581 | size = 16; |
| 582 | break; |
| 583 | default: |
| 584 | LM_ERR("unexpected af = %d\n",af); |
| 585 | return NULL; |
| 586 | } |
| 587 | |
| 588 | if (size != len) { |
| 589 | LM_ERR("size = %d, len = %d\n",size,len); |
| 590 | return NULL; |
| 591 | } |
| 592 | |
| 593 | cached_he = (struct hostent *)dnscache_fetch_func(addr,T_PTR,af==AF_INET?4:16); |
| 594 | if (cached_he == NULL) { |
| 595 | LM_DBG("not found in cache or other internal error\n"); |
| 596 | goto query; |
| 597 | } else if (cached_he == (void *)-1) { |
| 598 | LM_DBG("previously failed query\n"); |
| 599 | return NULL; |
| 600 | } else { |
| 601 | LM_DBG("cache hit for PTR - %d\n",af); |
| 602 | return cached_he; |
| 603 | } |
| 604 | |
| 605 | query: |
| 606 | switch (af) { |
| 607 | case AF_INET: |
| 608 | sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", |
| 609 | (uaddr[3] & 0xff), |
no test coverage detected