aboutsummaryrefslogtreecommitdiff
path: root/examples/ldns-testns.c
diff options
context:
space:
mode:
Diffstat (limited to 'examples/ldns-testns.c')
-rw-r--r--examples/ldns-testns.c85
1 files changed, 66 insertions, 19 deletions
diff --git a/examples/ldns-testns.c b/examples/ldns-testns.c
index 885453d3dcda..f1b9c7228d24 100644
--- a/examples/ldns-testns.c
+++ b/examples/ldns-testns.c
@@ -147,6 +147,15 @@ struct sockaddr_storage;
#include <netinet/igmp.h>
#endif
#include <errno.h>
+#include <signal.h>
+
+#ifdef HAVE_TARGETCONDITIONALS_H
+#include <TargetConditionals.h>
+#endif
+
+#if defined(TARGET_OS_TV) || defined(TARGET_OS_WATCH)
+#undef HAVE_FORK
+#endif
#define INBUF_SIZE 4096 /* max size for incoming queries */
#define DEFAULT_PORT 53 /* default if no -p port is specified */
@@ -272,7 +281,7 @@ handle_udp(int udp_sock, struct entry* entries, int *count)
&userdata, do_verbose?logfile:0);
}
-static void
+static int
read_n_bytes(int sock, uint8_t* buf, size_t sz)
{
size_t count = 0;
@@ -280,14 +289,14 @@ read_n_bytes(int sock, uint8_t* buf, size_t sz)
ssize_t nb = recv(sock, (void*)(buf+count), sz-count, 0);
if(nb < 0) {
log_msg("recv(): %s\n", strerror(errno));
- return;
+ return -1;
} else if(nb == 0) {
log_msg("recv: remote end closed the channel\n");
- memset(buf+count, 0, sz-count);
- return;
+ return sz-count;
}
count += nb;
}
+ return 0;
}
static void
@@ -325,7 +334,7 @@ handle_tcp(int tcp_sock, struct entry* entries, int *count)
struct sockaddr_storage addr_him;
socklen_t hislen;
uint8_t inbuf[INBUF_SIZE];
- uint16_t tcplen;
+ uint16_t tcplen = 0;
struct handle_tcp_userdata userdata;
/* accept */
@@ -336,23 +345,58 @@ handle_tcp(int tcp_sock, struct entry* entries, int *count)
}
userdata.s = s;
- /* tcp recv */
- read_n_bytes(s, (uint8_t*)&tcplen, sizeof(tcplen));
- tcplen = ntohs(tcplen);
- if(tcplen >= INBUF_SIZE) {
- log_msg("query %d bytes too large, buffer %d bytes.\n",
- tcplen, INBUF_SIZE);
+ while(1) {
+ /* tcp recv */
+ if (read_n_bytes(s, (uint8_t*)&tcplen, sizeof(tcplen))) {
#ifndef USE_WINSOCK
- close(s);
+ close(s);
#else
- closesocket(s);
+ closesocket(s);
#endif
- return;
- }
- read_n_bytes(s, inbuf, tcplen);
+ return;
+ }
+ tcplen = ntohs(tcplen);
+ if(tcplen >= INBUF_SIZE) {
+ log_msg("query %d bytes too large, buffer %d bytes.\n",
+ tcplen, INBUF_SIZE);
+#ifndef USE_WINSOCK
+ close(s);
+#else
+ closesocket(s);
+#endif
+ return;
+ }
+ if (read_n_bytes(s, inbuf, tcplen)) {
+#ifndef USE_WINSOCK
+ close(s);
+#else
+ closesocket(s);
+#endif
+ return;
+ }
+
+ handle_query(inbuf, (ssize_t) tcplen, entries, count, transport_tcp,
+ send_tcp, &userdata, do_verbose?logfile:0);
- handle_query(inbuf, (ssize_t) tcplen, entries, count, transport_tcp,
- send_tcp, &userdata, do_verbose?logfile:0);
+ /* another query straight away? */
+ if(1) {
+ fd_set rset;
+ struct timeval tv;
+ int ret;
+ FD_ZERO(&rset);
+ FD_SET(s, &rset);
+ tv.tv_sec = 0;
+ tv.tv_usec = 100*1000;
+ ret = select(s+1, &rset, NULL, NULL, &tv);
+ if(ret < 0) {
+ error("select(): %s\n", strerror(errno));
+ }
+ if(ret == 0) {
+ /* timeout */
+ break;
+ }
+ }
+ }
#ifndef USE_WINSOCK
close(s);
#else
@@ -407,7 +451,7 @@ forkit(int number)
int i;
for(i=0; i<number; i++)
{
-#ifndef HAVE_FORK
+#if !defined(HAVE_FORK) || !defined(HAVE_FORK_AVAILABLE)
#ifndef USE_WINSOCK
log_msg("fork() not available.\n");
exit(1);
@@ -499,6 +543,9 @@ main(int argc, char **argv)
log_msg("Reading datafile %s\n", datafile);
entries = read_datafile(datafile, 0);
+#ifdef SIGPIPE
+ (void)signal(SIGPIPE, SIG_IGN);
+#endif
#ifdef USE_WINSOCK
if(WSAStartup(MAKEWORD(2,2), &wsa_data) != 0)
error("WSAStartup failed\n");