예제 #1
0
void dns_handle_new_query(dns_request_t *m)
{
  //struct in_addr in;
  int retval = 0;	/* modified by CMC from retval=-1 2002/12/6 */

  if( m->message.question[0].type == A || m->message.question[0].type == AAA){
    /* added by CMC to deny name 2002/11/19 */
    if ( deny_lookup_name( m->cname ) ) 
    {
      debug("%s --> blocked.\n", m->cname);
      openlog("URL Filter", 0, 0);
      syslog(0, "URL access to %s is blocked\n", m->cname);
      closelog();
      dns_construct_error_reply(m);
      dns_write_packet( dns_sock, m->src_addr, m->src_port, m );
      return;
    }
    /* standard query */
    retval = cache_lookup_name( m->cname, m->ip );
  }else if( m->message.question[0].type == PTR ){
    /* reverse lookup */
    retval = cache_lookup_ip( m->ip, m->cname );
  }

  debug(".......... %s ---- %s\n", m->cname, m->ip );

  switch( retval )
    {
    case 0:
      if( is_connected() ){
	debug("Adding to list-> id: %d\n", m->message.header.id);
	dns_request_list = dns_list_add( dns_request_list, m );
	/* relay the query untouched */
	forward_dns_query( dns_request_list, m );  /* modified by CMC 8/3/2001 */
      }else{
	debug("Not connected **\n");
	dns_construct_error_reply(m);
	dns_write_packet( dns_sock, m->src_addr, m->src_port, m );
      }
      break;
    case 1:
      dns_construct_reply( m );
      dns_write_packet( dns_sock, m->src_addr, m->src_port, m );
      debug("Cache hit\n");
      break;
    default:
      debug("Unknown query type: %d\n", m->message.question[0].type );
      debug("CMC: Here is un-reachable code! (2002/12/6)\n");
    }

}
예제 #2
0
void dns_handle_request(dns_request_t *m)
{
  dns_request_t *ptr = NULL;

  /* request may be a new query or a answer from the upstream server */
  ptr = dns_list_find_by_id( dns_request_list, m );

  if( ptr != NULL ){
    debug("Found query in list\n");
    /* message may be a response */
    if( m->message.header.flags.f.question == 1 ){
      dns_write_packet( dns_sock, ptr->src_addr, ptr->src_port, m );
      debug("Replying with answer from %s\n", inet_ntoa( m->src_addr ));
      if( m->message.header.flags.f.rcode == 0 && /* modified by CMC 2002/12/6 */
          (ptr->message.question[0].type == A || ptr->message.question[0].type == PTR) ){
	debug("Cache append: %s ----> %s\n", m->cname, m->ip );
	cache_name_append( m->cname, m->ip );
      }
      dns_request_list = dns_list_remove( dns_request_list, ptr );
    }else{
      ptr->duplicate_queries++;	   /* added by CMC 8/4/2001 */
      debug("Duplicate query(%d)\n", ptr->duplicate_queries);
      forward_dns_query( ptr, m ); /* added by CMC 8/4/2001 */
    }
  }else{
    dns_handle_new_query( m );
  }

}
예제 #3
0
void dns_handle_new_query(dns_request_t *m)
{
  struct in_addr in;
  int retval = -1;

  if( m->message.question[0].type == A || m->message.question[0].type == AAA){
    /* standard query */
    retval = cache_lookup_name( m->cname, m->ip );
  }else if( m->message.question[0].type == PTR ){
    /* reverse lookup */
    retval = cache_lookup_ip( m->ip, m->cname );
  }

  debug(".......... %s ---- %s\n", m->cname, m->ip );
  
  switch( retval )
    {
    case 0:
      if( is_connected() ){
	debug("Adding to list-> id: %d\n", m->message.header.id);
	dns_request_list = dns_list_add( dns_request_list, m );
	/*!!! relay the query untouched */
		
	inet_aton( config.name_server[0], &in );
	debug("Sent Request To %s\n",config.name_server[0]);
        dns_write_packet( dns_sock, in, PORT, m ); 
      }else{
	debug("Not connected **\n");
	dns_construct_error_reply(m);
	dns_write_packet( dns_sock, m->src_addr, m->src_port, m );
      }
      break;
    case 1:
      dns_construct_reply( m );
      dns_write_packet( dns_sock, m->src_addr, m->src_port, m );
      debug("Cache hit\n");
      break;
    default:
      debug("Unknown query type: %d\n", m->message.question[0].type );
    }

}
예제 #4
0
int dns_main_loop()
{
  struct timeval tv;
  fd_set active_rfds;
  int retval;
  dns_request_t m;
  dns_request_t *ptr, *next;
  //int purge_time = config.purge_time / 60;
  int purge_time = CACHE_CHECK_TIME / DNS_TICK_TIME;	//(30sec) modified by CMC 8/4/2001

  while( !dns_main_quit ){

    /* set the one second time out */
    tv.tv_sec = DNS_TICK_TIME;	  //modified by CMC 8/3/2001
    tv.tv_usec = 0;

    /* now copy the main rfds in the active one as it gets modified by select*/
    active_rfds = rfds;

    retval = select( FD_SETSIZE, &active_rfds, NULL, NULL, &tv );

    if (retval){
      /* data is now available */
      dns_read_packet( dns_sock, &m );
      dns_handle_request( &m );
    }else{
      /* select time out */
      ptr = dns_request_list;
      while( ptr ){
	next = ptr->next;
	ptr->time_pending++;
	if( ptr->time_pending > DNS_TIMEOUT/DNS_TICK_TIME ){
	  /* CMC: ptr->time_pending= DNS_TIMEOUT ~ DNS_TIMEOUT+DNS_TICK_TIME */
	  debug("Request timed out\n");
	  /* send error back */
	  dns_construct_error_reply(ptr);
	  dns_write_packet( dns_sock, ptr->src_addr, ptr->src_port, ptr );
	  dns_request_list = dns_list_remove( dns_request_list, ptr );
	}
	ptr = next;
      } /* while(ptr) */

      /* purge cache */
      purge_time--;
      if( purge_time <= 0 ){			//modified by CMC 8/4/2001
	cache_purge( config.purge_time );
	//purge_time = config.purge_time / 60;
	purge_time = CACHE_CHECK_TIME / DNS_TICK_TIME; 	//(30sec) modified by CMC 8/3/2001
      }

    } /* if (retval) */
  }
  return 0;
}
예제 #5
0
/* This function is added by CMC 8/4/2001 */
void forward_dns_query(dns_request_t *node, dns_request_t *m)
{
  struct in_addr	in;
  FILE			*fp;
  char			line[81], dns_ser_ip[81];

  inet_aton( config.name_server, &in );

  if( (fp = fopen( "/etc/resolv.conf" , "r")) != NULL) {
	while ( fgets(line, 80, fp) != NULL ){
		if ( sscanf(line, "nameserver %s", dns_ser_ip) == 1 ){
			inet_aton( dns_ser_ip, &in );
			/* the first or lastest nameserver */
			if ( !(node->duplicate_queries & 0x01) )
				break;
		}
	}
	fclose(fp);
  }
  debug("forward_dns_query: query DNS server -- %s\n", inet_ntoa(in) );
  dns_write_packet( dns_sock, in, PORT, m );
}
예제 #6
0
void dns_handle_request(dns_request_t *m)
{
  dns_request_t *ptr = NULL;

  /* request may be a new query or a answer from the upstream server */
  ptr = dns_list_find_by_id( dns_request_list, m );

  if( ptr != NULL ){
    debug("Found query in list\n");
    /* message may be a response */
    if( m->message.header.flags.f.question == 1 ){
      if( m->message.header.flags.f.rcode == 0 ){ // lookup was succesful
        dns_write_packet( dns_sock, ptr->src_addr, ptr->src_port, m );
        debug("Replying with answer from %s\n", inet_ntoa( m->src_addr ));
        dns_request_list = dns_list_remove( dns_request_list, ptr );
	debug("Cache append: %s ----> %s\n", m->cname, m->ip );
	cache_name_append( m->cname, m->ip );
      }

    /*if( m->message.header.flags.f.question == 1 ){
      dns_write_packet( dns_sock, ptr->src_addr, ptr->src_port, m );
      debug("Replying with answer from %s\n", inet_ntoa( m->src_addr ));
      dns_request_list = dns_list_remove( dns_request_list, ptr );
      if( m->message.header.flags.f.rcode == 0 ){ // lookup was succesful
	debug("Cache append: %s ----> %s\n", m->cname, m->ip );
	cache_name_append( m->cname, m->ip );
      }*/

    }else{
      debug("Duplicate query\n");
    }
  }else{
    dns_handle_new_query( m );
  }

}
예제 #7
0
int dns_main_loop()
{
  struct timeval tv;
  fd_set active_rfds;
  int retval;
  dns_request_t m;
  dns_request_t *ptr, *next;
  int purge_time = config.purge_time / 60;

  int next_server_index = 0;
  struct in_addr in;

  while( !dns_main_quit ){

    /* set the one second time out */
    tv.tv_sec = 1;
    tv.tv_usec = 0;

    /* now copy the main rfds in the active one as it gets modified by select*/
    active_rfds = rfds;

    retval = select( FD_SETSIZE, &active_rfds, NULL, NULL, &tv );

    if (retval){
      /* data is now available */
      dns_read_packet( dns_sock, &m );
      m.time_pending = 0;
      dns_handle_request( &m );
    }else{
      /* select time out */
      ptr = dns_request_list;
      while( ptr ){
	next = ptr->next;
	/* Resend query to a new nameserver if response
	 * has not been received from the current nameserver */
	
	ptr->time_pending++;
	if( ptr->time_pending > DNS_TIMEOUT ){
	  debug("Request timed out\n");
	  /* send error back */
	  dns_construct_error_reply(ptr);
	  dns_write_packet( dns_sock, ptr->src_addr, ptr->src_port, ptr );
	  dns_request_list = dns_list_remove( dns_request_list, ptr );
	}
	if( ( ptr->time_pending % DNS_SERVER_TIMEOUT == 0) && 
	    ( ptr->time_pending < DNS_TIMEOUT) )
	{
          /* Send a request to the next nameserver */
          next_server_index = ptr->time_pending/DNS_SERVER_TIMEOUT;
	  /* If already the maximum number of supported servers have
	    been tried out then remove the request from the list and
	    send a response  back */
            if(next_server_index >= MAX_NAME_SERVER || 
			(config.name_server[next_server_index]  == NULL ))
            {
	  	/* send error back */
		debug("All Servers Tried: No Response\n");
	  	dns_construct_error_reply(ptr);
	  	dns_write_packet( dns_sock, ptr->src_addr, ptr->src_port, ptr );
	  	dns_request_list = dns_list_remove( dns_request_list, ptr );
                debug("Sent a DNS error message to Client \n");		
	    }
	    else
	    {
	      /* Create the new server IP address and relay the query untouched */
              inet_aton( config.name_server[next_server_index], &in );
	      /*!!!*/
	      debug("Didn't get a response from last server\n");
	      debug("Sending a new request to %s\n", config.name_server[next_server_index]);
	      /* Send the new request to the next name server */
	      dns_write_packet( dns_sock, in, PORT, ptr );	
	    }
		
	}
	ptr = next;
      } /* while(ptr) */

      /* purge cache */
      purge_time--;
      if( !purge_time ){
	cache_purge( config.purge_time );
	purge_time = config.purge_time / 60;
      } 

    } /* if (retval) */
  }  
  return 0;
}