⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dnsr_ask.c.svn-base

📁 域名解析器的实现
💻 SVN-BASE
字号:
/* include files declaration */
#include <l3/inc/phase2.h>
#include <l3/ap/dnsr/h/dns.h>
#include <l3/ap/dnsr/h/dnsr_if.h>


/*-----------------------------------------------------------------------
 * Constants
 *-----------------------------------------------------------------------
 */
 
/*-----------------------------------------------------------------------
 * Local Variables
 *-----------------------------------------------------------------------
 */  
/* Global variables */
/* Global variables */
static struct query_table query_db[DNS_MAX_QUERY];
static UI16_T dnsr_query_id;


/*-----------------------------------------------------------------------
 * Functions
 *-----------------------------------------------------------------------
 */  
/*------------------------------------------------------------------------
 * I16_T  dnsr_init_query_db()
 * Purpose:   initialize query List
 *          
 * Parameters:
 *    Input:
 *    Output:
 * returns :
 *------------------------------------------------------------------------
 */                     
void dnsr_init_query_db(void)
{       
    dnsr_query_id =0;
    memset(&query_db[0],0x0,sizeof(struct query_table)*DNS_MAX_QUERY);    
} /* init_query_db */


/*------------------------------------------------------------------------
 * I32_T  dnsr_get_query_id()
 * Purpose:   get the queue id from List
 *          
 * Parameters:
 *    Input:
 *    Output:
 * returns :
 *------------------------------------------------------------------------
 */                    
I32_T dnsr_get_query_id(PENDING_DNSR_MSG_PTR pMsg)
{
    I16_T i;
    struct sockaddr_in *client;
    UI32_T      client_ipa;
        
    /* get client IP address */
    client = (struct sockaddr_in *)&pMsg->client;
    client_ipa = client->sin_addr;
    
    for ( i=0 ; i < DNS_MAX_QUERY ; i++)
    {
        if (query_db[i].valid    != FALSE &&
            query_db[i].claddr   == client_ipa &&            
            query_db[i].clid     == pMsg->query_id)
	        return query_db[i].query_id;
    } /* for */
       
    /* not found the query index*/
    return -1;
} /* get_query_id_by_cldata */

/*------------------------------------------------------------------------
 * I32_T  dnsr_get_client_qid()
 * Purpose:   get the client query id from List
 *          
 * Parameters:
 *    Input:
 *    Output:
 * returns :
 *------------------------------------------------------------------------
 */                    
I32_T dnsr_get_client_qid(PENDING_DNSR_MSG_PTR pMsg)
{
    I16_T i;
    struct sockaddr_in *client;
    UI32_T      client_ipa;
        
    /* get client IP address */
    client = (struct sockaddr_in *)&pMsg->client;
    client_ipa = client->sin_addr;
    
    for ( i=0 ; i < DNS_MAX_QUERY ; i++)
    {
        if (query_db[i].valid    != FALSE &&
            query_db[i].claddr   == client_ipa &&            
            query_db[i].clid     == pMsg->query_id)
	        return query_db[i].clid;
    } /* for */
       
    /* not found the query index*/
    return -1;
} /* get_query_id_by_cldata */

/*------------------------------------------------------------------------
 * I16_T  dnsr_add_query()
 * Purpose:   add the pkt to List
 *          
 * Parameters:
 *    Input:
 *    Output:
 * returns :
 *------------------------------------------------------------------------
 */                    
I32_T dnsr_add_query(PENDING_DNSR_MSG_PTR pMsg)
{
    I16_T			i, free_index = DNS_MAX_QUERY ;
    struct sockaddr_in     *client;
    UI32_T          client_ipa;            
    
    for (i = 0 ; i < DNS_MAX_QUERY ; i++)
    {
        if (free_index == DNS_MAX_QUERY && query_db[i].valid == FALSE)
        {
            free_index=i;      
            break;
        }                    
    } /* for */
     
 
    if (free_index >=DNS_MAX_QUERY)
    {
#if DNSR_DEBUG
        DBG_L3_Printf("dnsr_add_query: add query failed\n");
#endif        
        return -1;
    }        
            
    /* get client IP address */
    client = (struct sockaddr_in *)&pMsg->client;
    client_ipa = client->sin_addr;
        
    /* if query table is not full, insert entry */        
    query_db[free_index].valid      = TRUE;
    query_db[free_index].query_id   = ++dnsr_query_id;            
    query_db[free_index].ptr		= pMsg;
    query_db[free_index].claddr		= client_ipa;    
    query_db[free_index].clid		= pMsg->query_id;                    
    query_db[free_index].now		= GLUE_NOW();    
                                        
    return query_db[free_index].query_id;      
} /* add_query_by_id */


/*------------------------------------------------------------------------
 * I16_T  dnsr_clear_query_id()
 * Purpose:   clear the specific query id
 *          
 * Parameters:
 *    Input:
 *    Output:
 * returns :
 *------------------------------------------------------------------------
 */                    
BOOLEAN_T dnsr_clear_query_id(UI32_T query_id)
{
    int i;
    
    for (i = 0 ; i < DNS_MAX_QUERY ; i++)
    {
        if (query_db[i].valid == FALSE)
            continue;
            
        if (query_db[i].query_id == query_id)
        {            
            if (query_db[i].ptr)
                OS_mem_free(query_db[i].ptr);
            memset(&query_db[i],0x0,sizeof(struct query_table));                                                     
            return TRUE;
        }                    
    } /* for */
    
	return FALSE;
}

/*------------------------------------------------------------------------
 * I16_T  dnsr_check_query_id()
 * Purpose:   check the query list
 *          
 * Parameters:
 *    Input:
 *    Output:
 * returns :
 *------------------------------------------------------------------------
 */                    
UI32_T dnsr_check_query_id(void) 
{
    I32_T  i;
    UI32_T time,ret_time = 0xffffffff;
    PENDING_DNSR_MSG_PTR pMsg;
    
    for(i = 0 ; i < DNS_MAX_QUERY ; i++)
    {
        if(query_db[i].valid)
        {                                                
            time =  GLUE_NOW() - query_db[i].now;
                                                
            if ((time) >= DNS_TIMEOUT_FLOOR)
            {
                /* retransmit the pkt */                
                query_db[i].now    = GLUE_NOW();                
                pMsg = (PENDING_DNSR_MSG_PTR)query_db[i].ptr;                
                
                query_db[i].query_id   = ++dnsr_query_id;            
                dns_encode_bits16((unsigned char *)pMsg->udp_data, query_db[i].query_id);
                if (DNSR_Send_Packet_To_Server(pMsg->udp_data,pMsg->udp_len,pMsg))
                {                                                            
                    /* assign timeer on next query timeout */
                    if (ret_time > DNS_TIMEOUT_FLOOR)
                        ret_time = DNS_TIMEOUT_FLOOR;
                }                        
            }                                   
            else
            {
                if ((DNS_TIMEOUT_FLOOR - time)< ret_time)
                    ret_time = DNS_TIMEOUT_FLOOR - time;
            }                                             
        }
    } /* for */
        
    return ret_time;
}
    
/*------------------------------------------------------------------------
 * I16_T  dnsr_abort()
 * Purpose:   clear the queue list
 *          
 * Parameters:
 *    Input:
 *    Output:
 * returns :
 *------------------------------------------------------------------------
 */                        
void dnsr_abort(void)
{
    int i;
    
    for (i = 0 ; i < DNS_MAX_QUERY ; i++)
    {
        if (query_db[i].valid == FALSE)
            continue;
                    
        if (query_db[i].ptr)
            OS_mem_free(query_db[i].ptr);
        memset(&query_db[i],0x0,sizeof(struct query_table));                                                 
    } /* for */
    return;

}
    
    
/*------------------------------------------------------------------------
 * I16_T  retrieve_query_by_id()
 * Purpose:   get packet content from index
 *          
 * Parameters:
 *    Input:
 *    Output:
 * returns :
 *------------------------------------------------------------------------
 */                       
void *retrieve_query_by_id(I16_T idx)
{       
    int i;
    
    if (idx < 0)    
        return 0 ;
        
    
    for (i = 0 ; i < DNS_MAX_QUERY ; i++)
    {
        if (query_db[i].valid == FALSE)
            continue;
                    
        if (query_db[i].query_id == idx)
            return query_db[i].ptr;        	                  
    } /* for */
            
    /* query id is null, do nothing */    
    return 0;
        
} /* retrieve_query_by_id */


/*------------------------------------------------------------------------
 * BOOLEAN_T  dns_ask()
 * Purpose:  handle DNS request packet.   
 *          
 * Parameters:
 *    Input:
 *    Output:
 * returns :
 *------------------------------------------------------------------------
 */                       
BOOLEAN_T dns_ask(unsigned char *qname,  
                   PENDING_DNSR_MSG_PTR pMsg
                  ) 
                     
{
    I32_T query_id;

    if (qname){}

	/* get query id */
    query_id = dnsr_get_query_id(pMsg);
        
    if (query_id<0)           /* got whole new client query */
    {
        /* allocate the new id */
        if ((query_id = dnsr_add_query(pMsg))<0)
            return FALSE;
    }
    else    
    {
        /* the request pkt is already existed in the Queue
        * do nothing 
        */        
        return FALSE;
    }            
           
   /*
    * Start network query.
    */    
    dns_encode_bits16((unsigned char *)pMsg->udp_data, query_id);
    DNSR_Send_Packet_To_Server(pMsg->udp_data,pMsg->udp_len,pMsg);

   /*
    * Query is now in progress, return FALSE to say so.
    */
    return TRUE;
}

/*------------------------------------------------------------------------
 * I16_T  dns_receive()
 * Purpose: handle DNS reply packet.
 *          
 * Parameters:
 *    Input:
 *    Output:
 * returns :
 *------------------------------------------------------------------------
 */                       
int dns_receive(PENDING_DNSR_MSG_PTR pMsg,                            
                struct dns_header *hdr,
                unsigned char *msg,
                unsigned msg_len)
{    
    struct dns_rr msg_rrs[DNS_MAX_RRS_PER_MSG];
    int  n;
    UI32_T query_id;
    enum dns_error err1;    
    enum dns_error err2;        
    BOOLEAN_T      ret;
    PENDING_DNSR_MSG_PTR    prMsg;

    memset(msg_rrs,0,sizeof(struct dns_rr)*DNS_MAX_RRS_PER_MSG);
         
    /* decode DNS Section entries */
    if (   ((n = dns_decode_rrs(msg, msg_len, hdr, msg_rrs, DNS_MAX_RRS_PER_MSG,GLUE_NOW())) < 0 )
        || ((UI16_T ) n < hdr->qdcount)
       )        
    
    {        
        return FALSE;
    }

    switch (err1 = dns_bless_message(msg, msg_len, hdr, msg_rrs, n)) 
    {

      case DNS_ERROR_OK: 
        /* hawa : the DNSR is not following DNS implementation, so add NO RECURSION to finish this task */
      case DNS_ERROR_NO_RECURSION:
           /*
            * Got something that looks like an answer, pass it up to application.
            */                   
        if (DNSR_Get_Cache_Status())  
        {
            /* add to cache */            
            if ((err2 = dns_cache_rrs(msg, msg_len, hdr, msg_rrs, n)) != DNS_ERROR_OK) 
            {                
                ret = FALSE;
                break;
            }
	     if(err2){}
        }   
         
        /* get Client id */ 
        prMsg = (PENDING_DNSR_MSG_PTR)retrieve_query_by_id(hdr->id);
        query_id = dnsr_get_client_qid(prMsg);
        dns_encode_bits16((unsigned char *)pMsg->udp_data, query_id);
        /* send to cLient */
        DNSR_Send_Packet_To_Client(pMsg->udp_data,pMsg->udp_len, prMsg);  
        
        /* clean the queue list */
        dnsr_clear_query_id(hdr->id);
        
                       
        ret = TRUE ;
        break;
                
      case DNS_ERROR_NO_RRS:
      case DNS_ERROR_NONEXISTANT_NAME:
      case DNS_ERROR_NAME_TOO_LONG:
      case DNS_ERROR_BAD_NAME:
      case DNS_ERROR_LABEL_TOO_LONG:
      case DNS_ERROR_FORMAT:
      case DNS_ERROR_SERVER_FAILURE:
      case DNS_ERROR_REFUSED:
      case DNS_ERROR_BAD_PROTOCOL:
      case DNS_ERROR_TRUNCATED:        
      case DNS_ERROR_IRRELEVANT:
       /*
        * Something weird about this message, discard it and keep trying.
        */			
        ret = FALSE;
        break;

      default:
       /*
        * Some other error that really shouldn't have happened here.
        * Tell application that we're losing and kill off the query.
        */        
        ret = TRUE;
        break;
    } /* switch */
     if(err1){}
    return ret;
} /* dns_receive */


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -