void ResolverPool_release(ResolverPool *self, DnsResolver *resolver) { if (NULL == resolver) { return; } // end if int ret = pthread_mutex_lock(&self->pool_lock); if (0 != ret) { LogError("pthread_mutex_lock failed: errno=%s", strerror(ret)); return; } // end if if (self->poolednum < self->maxslotnum) { self->slot[self->poolednum] = resolver; ++self->poolednum; resolver = NULL; } // end if ret = pthread_mutex_unlock(&self->pool_lock); if (0 != ret) { LogError("pthread_mutex_unlock failed: errno=%s", strerror(ret)); } // end if DnsResolver_free(resolver); } // end function: ResolverPool_release
void ResolverPool_free(ResolverPool *self) { if (NULL == self) { return; } // end if pthread_mutex_destroy(&self->pool_lock); for (size_t i = 0; i < self->poolednum; ++i) { DnsResolver_free(self->slot[i]); } // end for free(self); } // end function: ResolverPool_free
DnsResolver * DnsResolver_new(void) { DnsResolver *self = (DnsResolver *) malloc(sizeof(DnsResolver)); if (NULL == self) { return NULL; } // end if memset(self, 0, sizeof(DnsResolver)); if (NETDB_SUCCESS != res_ninit(&self->resolver)) { goto cleanup; } // end if self->resolv_errno = 0; self->resolv_h_errno = NETDB_SUCCESS; return self; cleanup: DnsResolver_free(self); return NULL; } // end function : DnsResolver_init
int main(int argc, char **argv) { int af = AF_UNSPEC; int ai_flags = 0; SidfRecordScope scope = SIDF_RECORD_SCOPE_SPF1; int c; while (-1 != (c = getopt(argc, argv, "46mnpshv"))) { switch (c) { case '4': // IPv4 af = AF_INET; break; case '6': // IPv6 af = AF_INET6; break; case 'm': // SIDF/mfrom scope = SIDF_RECORD_SCOPE_SPF2_MFROM; break; case 'n': // to prevent DNS-querying at getaddrinfo() ai_flags |= AI_NUMERICHOST; break; case 'p': // SIDF/pra scope = SIDF_RECORD_SCOPE_SPF2_PRA; break; case 's': // SPF scope = SIDF_RECORD_SCOPE_SPF1; break; case 'h': usage(stdout); break; case 'v': g_verbose_mode = true; break; default: fprintf(stdout, "[Error] illegal option: -%c\n", c); usage(stdout); break; } // end switch } // end while argc -= optind; argv += optind; if (argc < 2) { usage(stdout); } // end if DnsResolver *resolver = DnsResolver_new(); if (NULL == resolver) { fprintf(stdout, "[Error] resolver initialization failed: error=%s\n", strerror(errno)); exit(EX_OSERR); } // end if const char *mailbox = argv[0]; SidfPolicy *policy = SidfPolicy_new(); if (NULL == policy) { fprintf(stdout, "[Error] SidfPolicy_new failed: error=%s\n", strerror(errno)); exit(EX_OSERR); } // end if SidfPolicy_setSpfRRLookup(policy, true); SidfPolicy_setLogger(policy, stdout_logger); SidfRequest *request = SidfRequest_new(policy, resolver); if (NULL == request) { fprintf(stdout, "[Error] SidfRequest_new failed: error=%s\n", strerror(errno)); exit(EX_OSERR); } // end if const char *dummy; InetMailbox *envfrom = InetMailbox_build2822Mailbox(mailbox, STRTAIL(mailbox), &dummy, NULL); if (NULL == envfrom) { fprintf(stdout, "[Error] mailbox is not RFC2822 compliant: mailbox=%s\n", mailbox); usage(stdout); } // end if struct addrinfo ai_hints, *ai_result, *ai_current; memset(&ai_hints, 0, sizeof(struct addrinfo)); ai_hints.ai_flags |= ai_flags; ai_hints.ai_family = af; ai_hints.ai_socktype = SOCK_STREAM; for (int i = 1; i < argc; ++i) { int gai_error = getaddrinfo(argv[i], NULL, &ai_hints, &ai_result); if (0 != gai_error) { fprintf(stdout, "[Error] invalid IP address: ip-address=%s, error=%s\n", argv[i], gai_strerror(gai_error)); if (EAI_NONAME == gai_error) { continue; #ifdef EAI_NODATA } else if (EAI_NODATA == gai_error) { // some platforms have EAI_NODATA as a return code of getaddrinfo() continue; #endif // EAI_NODATA } else { exit(EX_OSERR); } // end if } // end if for (ai_current = ai_result; NULL != ai_current; ai_current = ai_current->ai_next) { if (AF_INET != ai_current->ai_family && AF_INET6 != ai_current->ai_family) { continue; } // end if char addr_string[INET6_ADDRSTRLEN]; if (AF_INET == ai_current->ai_family) { (void) inet_ntop(AF_INET, &((struct sockaddr_in *) ai_current->ai_addr)->sin_addr, addr_string, sizeof(addr_string)); } else { (void) inet_ntop(AF_INET6, &((struct sockaddr_in6 *) ai_current->ai_addr)->sin6_addr, addr_string, sizeof(addr_string)); } // end if SidfRequest_reset(request); if (!SidfRequest_setIpAddr(request, ai_current->ai_family, ai_current->ai_addr)) { fprintf(stdout, "[Error] SidfRequest_setIpAddr failed: address_family=0x%x\n", ai_current->ai_family); usage(stdout); } // end if SidfRequest_setSender(request, envfrom); SidfRequest_setHeloDomain(request, InetMailbox_getDomain(envfrom)); // SPF/Sender ID evaluation SidfScore score = SidfRequest_eval(request, scope); const char *spfresultexp = SidfEnum_lookupScoreByValue(score); fprintf(stdout, "%s %s %s\n", mailbox, addr_string, spfresultexp); } //end for freeaddrinfo(ai_result); } // end for // clean up InetMailbox_free(envfrom); SidfRequest_free(request); SidfPolicy_free(policy); DnsResolver_free(resolver); exit(EX_OK); } // end function : main