mirror of
https://github.com/ChronosX88/netsukuku.git
synced 2024-11-23 02:32:18 +00:00
176 lines
4.7 KiB
C
176 lines
4.7 KiB
C
/* 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
|
|
* modify it under the terms of the GNU General Public License as published
|
|
* 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 02139, 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
|
|
* resolved ip. In this way, every program can use ANDNA: just set
|
|
* "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
|
|
* the reply to from.
|
|
* `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);
|
|
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);
|
|
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
|
|
|
|
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");
|
|
|
|
FD_ZERO(&fdset);
|
|
FD_SET(sk, &fdset);
|
|
|
|
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
|
|
error("dns_wrapper_daemonp: select error: %s",
|
|
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));
|
|
|
|
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;
|
|
}
|
|
|
|
/* Exec the pkt in another thread */
|
|
exec_pkt_argv.sk=sk;
|
|
exec_pkt_argv.rpkt_sz=err;
|
|
exec_pkt_argv.rpkt=buf;
|
|
|
|
pthread_mutex_lock(&dns_exec_lock);
|
|
pthread_create(&thread, &t_attr, dns_exec_pkt,
|
|
(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;
|
|
}
|