2013-09-16 09:53:25 +00:00
/* This file is part of Netsukuku
* ( c ) Copyright 2005 Andrea Lo Pumo aka AlpT < alpt @ freaknet . org >
*
* This source code is free software ; you can redistribute it and / or
2014-03-19 01:29:15 +00:00
* modify it under the terms of the GNU General Public License as published
2013-09-16 09:53:25 +00:00
* by the Free Software Foundation ; either version 2 of the License ,
* or ( at your option ) any later version .
*
* This source code is distributed in the hope that it will be useful ,
* but WITHOUT ANY WARRANTY ; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE .
* Please refer to the GNU Public License for more details .
*
* You should have received a copy of the GNU Public License along with
* this source code ; if not , write to :
* Free Software Foundation , Inc . , 675 Mass Ave , Cambridge , MA 0213 9 , USA .
*
* - -
* dns_wrapper . c :
*
* The DNS wrapper listens to the port 53 for DNS hostname resolution queries ,
* it then resolves the hostname by using the ANDNA system and sends back the
2014-03-19 01:29:15 +00:00
* resolved ip . In this way , every program can use ANDNA : just set
2013-09-16 09:53:25 +00:00
* " nameserver localhost "
* in / etc / resolv . conf ; )
*/
# include "includes.h"
# include "inet.h"
# include "endianness.h"
# include "map.h"
# include "gmap.h"
# include "bmap.h"
# include "route.h"
# include "request.h"
# include "pkts.h"
# include "tracer.h"
# include "qspn.h"
# include "radar.h"
# include "netsukuku.h"
# include "daemon.h"
# include "crypto.h"
# include "andna_cache.h"
# include "andna.h"
# include "andns.h"
# include "dns_wrapper.h"
# include "common.h"
/*
* dns_exec_pkt : resolve the hostname contained in the DNS query and sends
2014-03-19 01:29:15 +00:00
* the reply to from .
2013-09-16 09:53:25 +00:00
* ` passed_argv ' is a pointer to a dns_exec_pkt_argv struct .
*/
void * dns_exec_pkt ( void * passed_argv )
{
struct dns_exec_pkt_argv argv ;
char buf [ MAX_DNS_PKT_SZ ] ;
char answer_buffer [ ANDNS_MAX_SZ ] ;
int answer_length ;
int bytes_sent ;
memcpy ( & argv , passed_argv , sizeof ( struct dns_exec_pkt_argv ) ) ;
memcpy ( & buf , argv . rpkt , argv . rpkt_sz ) ;
pthread_mutex_unlock ( & dns_exec_lock ) ;
if ( argv . rpkt_sz < MIN_PKT_SZ ) {
debug ( DBG_NORMAL , " Received malformed DNS packet " ) ;
return 0 ;
}
/* Unpack the DNS query and resolve the hostname */
if ( ! andns_rslv ( buf , argv . rpkt_sz , answer_buffer , & answer_length ) )
return 0 ;
/* Send the DNS reply */
bytes_sent = inet_sendto ( argv . sk , answer_buffer , answer_length , 0 ,
& argv . from , argv . from_len ) ;
2014-03-19 01:29:15 +00:00
error ( " bytes_sent is: %d argv.sk is: %d answer_buffer is: %s answer_length is: %d argv.from is: %p agrv.from_len is: %p " , bytes_sent , argv . sk , answer_buffer , answer_length , argv . from , argv . from_len ) ;
2013-09-16 09:53:25 +00:00
if ( bytes_sent ! = answer_length )
debug ( DBG_SOFT , ERROR_MSG " inet_sendto error: %s " , ERROR_POS ,
strerror ( errno ) ) ;
return 0 ;
}
/*
* dns_wrapper_daemon : It receives DNS query pkts , resolves them in ANDNA and
* replies with a DNS reply .
* It listens to ` port ' .
*/
void dns_wrapper_daemon ( u_short port )
{
struct dns_exec_pkt_argv exec_pkt_argv ;
char buf [ MAX_DNS_PKT_SZ ] ;
fd_set fdset ;
int ret , sk ;
pthread_t thread ;
pthread_attr_t t_attr ;
ssize_t err = - 1 ;
# ifdef DEBUG
int select_errors = 0 ;
# endif
2014-03-19 01:29:15 +00:00
2013-09-16 09:53:25 +00:00
pthread_attr_init ( & t_attr ) ;
pthread_attr_setdetachstate ( & t_attr , PTHREAD_CREATE_DETACHED ) ;
pthread_mutex_init ( & dns_exec_lock , 0 ) ;
debug ( DBG_SOFT , " Preparing the dns_udp listening socket on port %d " , port ) ;
sk = prepare_listen_socket ( my_family , SOCK_DGRAM , port , 0 ) ;
if ( sk = = - 1 )
return ;
debug ( DBG_NORMAL , " DNS wrapper daemon on port %d up & running " , port ) ;
for ( ; ; ) {
if ( ! sk )
fatal ( " The dns_wrapper_daemon socket got corrupted " ) ;
2014-03-19 01:29:15 +00:00
2013-09-16 09:53:25 +00:00
FD_ZERO ( & fdset ) ;
FD_SET ( sk , & fdset ) ;
2014-03-19 01:29:15 +00:00
2013-09-16 09:53:25 +00:00
ret = select ( sk + 1 , & fdset , NULL , NULL , NULL ) ;
if ( sigterm_timestamp )
/* NetsukukuD has been closed */
break ;
if ( ret < 0 ) {
# ifdef DEBUG
if ( select_errors > 20 )
break ;
select_errors + + ;
# endif
2014-03-19 01:29:15 +00:00
error ( " dns_wrapper_daemonp: select error: %s " ,
2013-09-16 09:53:25 +00:00
strerror ( errno ) ) ;
continue ;
}
if ( ! FD_ISSET ( sk , & fdset ) )
continue ;
setzero ( & buf , MAX_DNS_PKT_SZ ) ;
setzero ( & exec_pkt_argv . from , sizeof ( struct sockaddr ) ) ;
setzero ( & exec_pkt_argv , sizeof ( struct dns_exec_pkt_argv ) ) ;
2014-03-19 01:29:15 +00:00
2013-09-16 09:53:25 +00:00
exec_pkt_argv . from_len = my_family = = AF_INET ?
sizeof ( struct sockaddr_in ) : sizeof ( struct sockaddr_in6 ) ;
/* we get the DNS query */
err = inet_recvfrom ( sk , buf , MAX_DNS_PKT_SZ , MSG_WAITALL ,
& exec_pkt_argv . from , & exec_pkt_argv . from_len ) ;
if ( err < 0 ) {
debug ( DBG_NOISE , " dns_wrapper_daemonp: recv of the dns "
" query pkt aborted! " ) ;
continue ;
}
2014-03-19 01:29:15 +00:00
2013-09-16 09:53:25 +00:00
/* Exec the pkt in another thread */
exec_pkt_argv . sk = sk ;
exec_pkt_argv . rpkt_sz = err ;
exec_pkt_argv . rpkt = buf ;
2014-03-19 01:29:15 +00:00
2013-09-16 09:53:25 +00:00
pthread_mutex_lock ( & dns_exec_lock ) ;
2014-03-19 01:29:15 +00:00
pthread_create ( & thread , & t_attr , dns_exec_pkt ,
2013-09-16 09:53:25 +00:00
( void * ) & exec_pkt_argv ) ;
pthread_mutex_lock ( & dns_exec_lock ) ;
pthread_mutex_unlock ( & dns_exec_lock ) ;
}
}
void * dns_wrapper_thread ( void * null )
{
dns_wrapper_daemon ( DNS_WRAPPER_PORT ) ;
return 0 ;
}