ACL_DNS_DB *acl_netdb_clone(const ACL_DNS_DB *db) { ACL_DNS_DB *dbp; ACL_HOSTNAME *phost, *h_host; int i, n; if (db == NULL || db->h_db == NULL) return NULL; n = acl_array_size(db->h_db); if (n <= 0) { acl_msg_error("%s, %s(%d): h_db's size(%d) <= 0", __FILE__, __FUNCTION__, __LINE__, n); return NULL; } dbp = acl_netdb_new(db->name); for (i = 0; i < n; i++) { phost = (ACL_HOSTNAME *) acl_array_index(db->h_db, i); acl_assert(phost); h_host = acl_mycalloc(1, sizeof(ACL_HOSTNAME)); memcpy(&h_host->saddr, &phost->saddr, sizeof(h_host->saddr)); ACL_SAFE_STRNCPY(h_host->ip, phost->ip, sizeof(h_host->ip)); h_host->hport = phost->hport; (void) acl_array_append(dbp->h_db, h_host); dbp->size++; } return dbp; }
ACL_DNS_DB *acl_netdb_clone(const ACL_DNS_DB *h_dns_db) { const char *myname = "acl_netdb_clone"; char buf[256]; ACL_DNS_DB *dns_db; ACL_HOSTNAME *phost, *h_host; int i, n; if (h_dns_db == NULL || h_dns_db->h_db == NULL) return (NULL); n = acl_array_size(h_dns_db->h_db); if (n <= 0) { acl_msg_error("%s, %s(%d): h_db's size(%d) <= 0", __FILE__, myname, __LINE__, n); return (NULL); } dns_db = acl_netdb_new(h_dns_db->name); if (dns_db == NULL) { acl_msg_error("%s, %s(%d): acl_netdb_new error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); return (NULL); } for (i = 0; i < n; i++) { phost = (ACL_HOSTNAME *) acl_array_index(h_dns_db->h_db, i); acl_assert(phost); h_host = acl_mycalloc(1, sizeof(ACL_HOSTNAME)); if (h_host == NULL) { acl_msg_error("%s, %s(%d): calloc error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); acl_netdb_free(dns_db); return (NULL); } h_host->saddr.sin_addr.s_addr = phost->saddr.sin_addr.s_addr; ACL_SAFE_STRNCPY(h_host->ip, phost->ip, sizeof(h_host->ip)); h_host->hport = phost->hport; if (acl_array_append(dns_db->h_db, h_host) < 0) { acl_msg_error("%s, %s(%d): array append error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); acl_netdb_free(dns_db); return (NULL); } dns_db->size++; } return (dns_db); }
ACL_DNS_DB *acl_gethostbyname(const char *name, int *h_error) { char myname[] = "acl_gethostbyname"; ACL_DNS_DB *h_dns_db = NULL; ACL_HOSTNAME *h_host; /* #ifndef SUNOS5 */ struct hostent *h_addrp = NULL; /* #endif */ #ifdef ACL_UNIX # ifndef ACL_MACOSX struct hostent h_buf; int errnum = 0; # endif #endif char **pptr, buf[4096]; int n; #undef ERETURN #define ERETURN(_x_) do { \ if (h_dns_db) \ acl_netdb_free(h_dns_db); \ return (_x_); \ } while (0) if (name == NULL) { acl_msg_error("%s, %s(%d): input error", __FILE__, myname, __LINE__); ERETURN (NULL); } if (h_error) *h_error = 0; /* lookup the local dns cache first */ h_dns_db = acl_netdb_cache_lookup(name); if (h_dns_db) return (h_dns_db); h_dns_db = acl_netdb_new(name); if (h_dns_db == NULL) { acl_msg_error("%s, %s(%d): acl_netdb_new error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); return (NULL); } if (acl_is_ip(name) == 0) { h_host = acl_mycalloc(1, sizeof(ACL_HOSTNAME)); if (h_host == NULL) { acl_msg_error("%s, %s(%d): calloc error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); ERETURN (NULL); } h_host->saddr.sin_addr.s_addr = inet_addr(name); ACL_SAFE_STRNCPY(h_host->ip, name, sizeof(h_host->ip)); if (acl_array_append(h_dns_db->h_db, h_host) < 0) { acl_msg_error("%s, %s(%d): array append error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); ERETURN (NULL); } h_dns_db->size++; return (h_dns_db); } memset(buf, 0, sizeof(buf)); h_addrp = NULL; #if defined(ACL_MS_WINDOWS) || defined(ACL_MACOSX) h_addrp = gethostbyname(name); if (h_addrp == NULL) { acl_msg_error("%s, %s(%d): gethostbyname error(%s), addr=%s", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf)), name); ERETURN (NULL); } #elif defined(ACL_UNIX) memset(&h_buf, 0, sizeof(h_buf)); # if defined(LINUX2) || defined(ACL_FREEBSD) n = gethostbyname_r(name, &h_buf, buf, sizeof(buf), &h_addrp, &errnum); if (n) { if (h_error) *h_error = errnum; ERETURN (NULL); } # elif defined(SUNOS5) h_addrp = gethostbyname_r(name, &h_buf, buf, sizeof(buf), &errnum); if (h_addrp == NULL) { if (h_error) *h_error = errnum; ERETURN (NULL); } # else # error "unknown OS type" # endif #else # error "unknown OS type" #endif if (h_addrp == NULL || h_addrp->h_addr_list == NULL) { acl_msg_error("%s, %s(%d): null result return(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); ERETURN (NULL); } for (pptr = h_addrp->h_addr_list; *pptr != NULL; pptr++) { h_host = acl_mycalloc(1, sizeof(ACL_HOSTNAME)); if (h_host == NULL) { acl_msg_error("%s, %s(%d): calloc error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); ERETURN (NULL); } memset(&h_host->saddr, 0, sizeof(h_host->saddr)); n = (int) sizeof(h_host->saddr.sin_addr) > h_addrp->h_length ? h_addrp->h_length : (int) sizeof(h_host->saddr.sin_addr); memcpy(&h_host->saddr.sin_addr, *pptr, n); /* bugifx: 2009.12.8 * this is not thread safe * ACL_SAFE_STRNCPY(h_host->ip, inet_ntoa(h_host->saddr.sin_addr), sizeof(h_host->ip)); */ acl_inet_ntoa(h_host->saddr.sin_addr, h_host->ip, sizeof(h_host->ip)); if (acl_array_append(h_dns_db->h_db, h_host) < 0) { acl_msg_error("%s, %s(%d): array append error(%s)", __FILE__, myname, __LINE__, acl_last_strerror(buf, sizeof(buf))); ERETURN (NULL); } h_dns_db->size++; } acl_netdb_cache_push(h_dns_db, 0); return (h_dns_db); }
ACL_DNS_DB *acl_gethostbyname(const char *name, int *h_error) { ACL_DNS_DB *db; ACL_SOCKADDR saddr; struct addrinfo *res0, *res; if (h_error) *h_error = 0; /* lookup the local dns cache first */ db = acl_netdb_cache_lookup(name); if (db) return db; db = acl_netdb_new(name); if (ip2addr(name, 0, &saddr)) { ACL_HOSTNAME *h_host = acl_mycalloc(1, sizeof(ACL_HOSTNAME)); memcpy(&h_host->saddr, &saddr, sizeof(h_host->saddr)); ACL_SAFE_STRNCPY(h_host->ip, name, sizeof(h_host->ip)); (void) acl_array_append(db->h_db, h_host); db->size++; return db; } res0 = acl_host_addrinfo(name, SOCK_DGRAM); if (res0 == NULL) return NULL; for (res = res0; res != NULL; res = res->ai_next) { ACL_SOCKADDR *sa = (ACL_SOCKADDR *) res->ai_addr; ACL_HOSTNAME *h_host; char ip[64]; memset(&saddr, 0, sizeof(saddr)); saddr.sa.sa_family = res->ai_family; if (res->ai_family == AF_INET) { if (inet_ntop(res->ai_family, &sa->in.sin_addr, ip, sizeof(ip)) == NULL) { continue; } memcpy(&saddr.in.sin_addr, &sa->in.sin_addr, sizeof(saddr.in.sin_addr)); #ifdef AF_INET6 } else if (res->ai_family == AF_INET6) { if (inet_ntop(res->ai_family, &sa->in6.sin6_addr, ip, sizeof(ip)) == NULL) { continue; } memcpy(&saddr.in6.sin6_addr, &sa->in6.sin6_addr, sizeof(saddr.in6.sin6_addr)); #endif } else { continue; } h_host = (ACL_HOSTNAME*) acl_mycalloc(1, sizeof(ACL_HOSTNAME)); memcpy(&h_host->saddr, &saddr, sizeof(h_host->saddr)); ACL_SAFE_STRNCPY(h_host->ip, ip, sizeof(h_host->ip)); h_host->hport = 0; (void) acl_array_append(db->h_db, h_host); db->size++; } freeaddrinfo(res0); if (acl_netdb_size(db) > 0) return db; acl_netdb_free(db); return NULL; }