! \brief gets the DNS records for name:type * \return A dyn. alloc'ed struct rdata linked list with the parsed responses * or 0 on error * \note see rfc1035 for the query/response format */
| 1093 | * or 0 on error |
| 1094 | * \note see rfc1035 for the query/response format */ |
| 1095 | struct rdata* get_record(char* name, int type) |
| 1096 | { |
| 1097 | int size; |
| 1098 | int qno, answers_no; |
| 1099 | int r; |
| 1100 | static union dns_query buff; |
| 1101 | unsigned char* p; |
| 1102 | /* unsigned char* t; |
| 1103 | int ans_len; |
| 1104 | static unsigned char answer[ANS_SIZE]; */ |
| 1105 | static int rdata_struct_len=sizeof(struct rdata)-sizeof(void *) - |
| 1106 | sizeof(struct rdata *); |
| 1107 | unsigned char* end; |
| 1108 | unsigned short rtype, class, rdlength; |
| 1109 | unsigned int ttl; |
| 1110 | unsigned int min_ttl = UINT_MAX; |
| 1111 | struct rdata* head; |
| 1112 | struct rdata** crt; |
| 1113 | struct rdata** last; |
| 1114 | struct rdata* rd; |
| 1115 | struct srv_rdata* srv_rd; |
| 1116 | struct srv_rdata* crt_srv; |
| 1117 | struct naptr_rdata* naptr_rd; |
| 1118 | struct txt_rdata* txt_rd; |
| 1119 | struct ebl_rdata* ebl_rd; |
| 1120 | struct timeval start; |
| 1121 | int rdata_buf_len=0; |
| 1122 | |
| 1123 | if (dnscache_fetch_func != NULL) { |
| 1124 | head = (struct rdata *)dnscache_fetch_func(name,type,0); |
| 1125 | if (head == NULL) { |
| 1126 | LM_DBG("not found in cache or other internal error\n"); |
| 1127 | goto query; |
| 1128 | } else if (head == (void *)-1) { |
| 1129 | LM_DBG("previously failed query\n"); |
| 1130 | goto not_found; |
| 1131 | } else { |
| 1132 | LM_DBG("cache hit for %s - %d\n",name,type); |
| 1133 | return head; |
| 1134 | } |
| 1135 | } |
| 1136 | |
| 1137 | query: |
| 1138 | start_expire_timer(start,execdnsthreshold); |
| 1139 | size=res_search(name, C_IN, type, buff.buff, sizeof(buff)); |
| 1140 | _stop_expire_timer(start, execdnsthreshold, "dns", |
| 1141 | name, strlen(name), 0, dns_slow_queries, dns_total_queries); |
| 1142 | |
| 1143 | if (size<0) { |
| 1144 | LM_DBG("lookup(%s, %d) failed\n", name, type); |
| 1145 | if (dnscache_put_func != NULL) { |
| 1146 | if (dnscache_put_func(name,type,NULL,0,1,0) < 0) |
| 1147 | LM_ERR("Failed to store %s - %d in cache\n",name,type); |
| 1148 | } |
| 1149 | goto not_found; |
| 1150 | } |
| 1151 | else if ((unsigned int)size > sizeof(buff)) size=sizeof(buff); |
| 1152 | head=rd=0; |
no test coverage detected