📄 dns_client_statics.c
字号:
/* ############################################################################ (c) Copyright GlobespanVirata Limited 2003## GlobespanVirata Limited Confidential and Proprietary## The following software source code ("Software") is strictly confidential and# is proprietary to GlobespanVirata. It may only be read, used, copied, # adapted, modified or otherwise dealt with by you if you have entered into a# confidentiality agreement with GlobespanVirata and then subject to the terms# of that confidentiality agreement and any other applicable agreement between# you and GlobespanVirata. If you are in any doubt as to whether you are # entitled to access, read, use, copy, adapt, modify or otherwise deal with# the Software or whether you are entitled to disclose the Software to any # other person you should contact GlobespanVirata. If you have not entered # into a confidentiality agreement with GlobespanVirata granting access to # this Software you should forthwith return all media, copies and printed# listings containing the Software to GlobespanVirata. ## GlobespanVirata reserves the right to take legal action against you should # you breach the above provisions.## If you are unsure, or to report violations, please contact # support@globespanvirata.com# ##########################################################################*//* dns_client_statics.c *//* Handling of query states and other static arrays has been moved here from * dns_client_resource.c since they are private to the DNS client. That file * now only contains structure alloc and free functions, and no longer uses * any static storage. This is intended to allow DNS relay to utilise the * functions there without incurring a memory cost (as well as reducing * up-front memory usage in general). */#include <stdlib.h>#include "dns_resolv.h"#include "dns_client_resource.h"#include "dns_client_statics.h"static QueryState qs_resource[MAXQS]; /* QueryState structures */#ifdef DNS_DEBUGstatic int ncnt; /* number of used QueryState's from npool */static int nfail; /* number of times allocation attempt failed */#endif/* * hpool is used for "support" or "internal" queries. (I call them by both names * in the comments.) nlp_pool is used for queries generated by the command line * nslookup. */static nslook_t hpool[MAXMSGHOSTENT]; /* space for addresses in dns_hostent */#ifdef DNS_DEBUGstatic int hpcnt; /* number of ip pools in use */static int hpfail; /* number of times ip pool allocation failed */#endifstatic nslook_t nlp_pool[MAXNLP]; /* messages and dns_hostent for nslookup */#ifdef DNS_DEBUGstatic int nlpcnt; /* number of nlp in use */static int nlpfail; /* number of times nlp allocation failed */#endif/* Initialise all QueryState structures */voidinit_pkt_resources(){ memset(qs_resource, 0, (MAXQS*sizeof(QueryState))); memset(hpool, 0, (MAXMSGHOSTENT*sizeof(nslook_t))); memset(nlp_pool, 0, (MAXNLP*sizeof(nslook_t))); return;}/* * dns_get_querystate() * * this routine will loop through the array of our QueryState structures * and return a pointer to the first one that is marked unused. * * return: pointer to a free QueryState, or * NULL; */QueryState *dns_get_querystate(){ int i; for ( i = 0; i < MAXQS; i++ ) { if ( FALSE == qs_resource[i].used ) { memset(qs_resource + i, 0, sizeof(qs_resource[i])); qs_resource[i].used = TRUE;#ifdef DNS_DEBUG ncnt++;#endif return &qs_resource[i]; } }#ifdef DNS_DEBUG nfail++;#endif return NULL;} /* end dns_get_querystate() *//* * free_querystate() * * this routine will set the query state entry to unused. it also sets the * next query pointer to null. */voidfree_querystate(QueryState *qs){ ASSERT(qs->used == TRUE); qs->used = FALSE; qs->nxquery = NULL;#ifdef DNS_DEBUG ncnt--;#endif}/* * Calculate difference (time1 - time2) between two timeouts in * timeval structures and return result in milliseconds * (microseconds are rounded to upper limit) */#define DIFFTIMEVAL2MS(p_time1, p_time2) \ (((p_time1)->tv_sec - (p_time2)->tv_sec) * 1000 + \ ((p_time1)->tv_usec - (p_time2)->tv_usec) / 1000) /* dns_client_query_timeout -- * Calls specified in parameters callback for each timed out * query state * * PARAMETERS: * current - current time value (maximum to timeout all queries) * callback - function to be called for each timed out QueryState * * RETURNS: * minimum timeout for all queries after decrement, but before * calling of callback function for timed out queries (if query * is not discarded, then next request is sent and timeout for * posted query is set up in dns_client_timeout variable in * dns_client_skt.c) */u_longdns_client_query_timeout(struct timeval *current, dns_client_query_callback callback){ int i; long timeout; long min_timeout; DNSC_DEBUG("entry - current time %d.%06d\n", current->tv_sec, current->tv_usec); /* * For each QueryState decrese its timeout and * call supplied callback function if it's necessary */ for (min_timeout = 0, i = 0; i < MAXQS; i++) { if (qs_resource[i].used == TRUE) { DNSC_DEBUG("query #%d deadline %d.%06d\n", i, qs_resource[i].deadline.tv_sec, qs_resource[i].deadline.tv_usec); timeout = DIFFTIMEVAL2MS(&qs_resource[i].deadline, current); if (timeout <= 0) { DNSC_DEBUG("call callback function\n"); callback(&qs_resource[i]); } else { if ((timeout < min_timeout) || (min_timeout == 0)) { min_timeout = timeout; } } } } DNSC_DEBUG("exit - min_timeout %d\n", min_timeout); return min_timeout;} /* dns_client_query_timeout */#undef DIFFTIMEVAL2MS/* * search routines * * these routines loop though the array of QueryState structures and return * a pointer to the matching structure. the match is determined by either * the time out message or DNS message id. note that we don't attempt to * match any structure that is not in use, since those structures are not * considered to be in the wait list. * * return: pointer to the matching QueryState, or * NULL if no match. */QueryState *search_wait_list_id(U16 id){ int i; for ( i = 0; i < MAXQS; i++ ) { if ( TRUE == qs_resource[i].used ) { if ( id == qs_resource[i].qid ) return &qs_resource[i]; } } return NULL;} /* end search_wait_list_id() */QueryState *search_wait_list_reply(ATMOS_MESSAGE *nextquery){ int i; for ( i = 0; i < MAXQS; i++ ) { if ( TRUE == qs_resource[i].used && qs_resource[i].nxquery == nextquery ) return &qs_resource[i]; } return NULL;} /* end search_wait_list_reply() *//* * dns_hent_alloc() * * this routine is used to allocate nslook_t structures from the hpool list. * these are used to aquire the struct dns_hostent and ATMOS_MESSAGE for an internal * query. * * return: pointer to free nslook_t structure, or * NULL if there are none available. */nslook_t *dns_hent_alloc(){ int i; DNSC_DEBUG("entry\n"); for ( i = 0; i < MAXMSGHOSTENT; i++ ) { if ( FALSE == hpool[i].used ) {#ifdef DNS_DEBUG hpcnt++;#endif memset(&hpool[i].hent, 0, sizeof(struct dns_hostent)); hpool[i].hent6 = NULL; hpool[i].used = TRUE; hpool[i].hent.h_addr_list = hpool[i].addrs; DNSC_DEBUG("exit - #%d 0x%08x\n", i, &hpool[i]); return &hpool[i]; } }#ifdef DNS_DEBUG hpfail++;#endif return NULL;} /* end dns_hent_alloc() *//* * dns_hent_free(), dns_hent_msg_free() and dns_hent_host_free() * * these routines are used to free a nslook_t sturture from the hpool list. * they provide different ways of releasing the structure element. */voiddns_hent_free(nslook_t *hp){ DNSC_DEBUG("entry - exit 0x%08x\n", hp); ASSERT(hp->used == TRUE); if (hp->hent6 != NULL) { dns_freehostent(hp->hent6); hp->hent6 = NULL; } hp->used = FALSE;#ifdef DNS_DEBUG --hpcnt;#endif} /* end dns_hent_free() */ voiddns_hent_msg_free(ATMOS_MESSAGE *msg){ int i; DNSC_DEBUG("entry\n"); for ( i = 0; i < MAXMSGHOSTENT; i++ ) { if ( &hpool[i].amsg == msg ) { if (hpool[i].hent6 != NULL) { dns_freehostent(hpool[i].hent6); hpool[i].hent6 = NULL; } ASSERT(hpool[i].used == TRUE); hpool[i].used = FALSE; DNSC_DEBUG("free #%d 0x%08x\n", i, &hpool[i]);#ifdef DNS_DEBUG --hpcnt;#endif return; } } ASSERT(FALSE);} /* end dns_hent_msg_free() */voiddns_hent_host_free(struct dns_hostent *ht){ int i; DNSC_DEBUG("entry\n"); for ( i = 0; i < MAXMSGHOSTENT; i++ ) { if ( &hpool[i].hent == ht ) { if (hpool[i].hent6 != NULL) { dns_freehostent(hpool[i].hent6); hpool[i].hent6 = NULL; } ASSERT(hpool[i].used == TRUE); hpool[i].used = FALSE; DNSC_DEBUG("free #%d 0x%08x\n", i, &hpool[i]);#ifdef DNS_DEBUG --hpcnt;#endif return; } } ASSERT(FALSE);} /* end dns_hent_host_free() *//* * dns_nslkup_alloc() * * this routine will find and return an unused nslook_t element from the nlp_pool. * these are used for queries started from the command line with the nslookup * command. * * return: pointer to the first free nlp_pool element, or * NULL if there are no unused elements. */nslook_t *dns_nslkup_alloc(){ int i; for ( i = 0; i < MAXNLP; i++ ) { if ( FALSE == nlp_pool[i].used ) {#ifdef DNS_DEBUG nlpcnt++;#endif memset(&nlp_pool[i].hent, 0, sizeof(struct dns_hostent)); nlp_pool[i].hent6 = NULL; nlp_pool[i].used = TRUE; nlp_pool[i].hent.h_addr_list = nlp_pool[i].addrs; return &nlp_pool[i]; } }#ifdef DNS_DEBUG nlpfail++;#endif return NULL;} /* end dns_nslkup_alloc() *//* * dns_nslkup_free(), dns_nslkup_msg_free() and dns_nslkup_host_free() * * these routines provide different methods of releasing a nslook_t structure * allocated from the nlp_pool. */voiddns_nslkup_free(nslook_t *hp){ ASSERT(hp->used == TRUE); hp->used = FALSE; if (hp->hent6 != NULL) { dns_freehostent(hp->hent6); hp->hent6 = NULL; }#ifdef DNS_DEBUG --nlpcnt;#endif} /* end dns_nslkup_free() */voiddns_nslkup_msg_free(ATMOS_MESSAGE *msg){ int i; for ( i = 0; i < MAXNLP; i++ ) { if ( &nlp_pool[i].amsg == msg ) { ASSERT(nlp_pool[i].used == TRUE); if (nlp_pool[i].hent6 != NULL) { dns_freehostent(nlp_pool[i].hent6); nlp_pool[i].hent6 = NULL; } nlp_pool[i].used = FALSE;#ifdef DNS_DEBUG --nlpcnt;#endif } }} /* end dns_nslkup_msg_free() */voiddns_nslkup_host_free(struct dns_hostent *ht){ int i; for ( i = 0; i < MAXNLP; i++ ) { if ( &nlp_pool[i].hent == ht ) { ASSERT(nlp_pool[i].used == TRUE); if (nlp_pool[i].hent6 != NULL) { dns_freehostent(nlp_pool[i].hent6); nlp_pool[i].hent6 = NULL; } nlp_pool[i].used = FALSE;#ifdef DNS_DEBUG --nlpcnt;#endif } }} /* end dns_nslkup_host_free() *//* * dns_nslkup_locate() * * this routine will try to match the pointer of the ATMOS_MESSAGE message to * one of the elements of the nlp_pool list. this allows us to tell if the * message is for an internal query or from a query from the command line nslookup * command. a match indicates the command line. * * return: TRUE if there is a match, * FALSE if not. */BOOLdns_nslkup_locate(ATMOS_MESSAGE *msg){ int i; for ( i = 0; i < MAXNLP; i++ ) { if ( &nlp_pool[i].amsg == msg ) return TRUE; } return FALSE;} /* end dns_nslkup_locate() */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -