aboutsummaryrefslogtreecommitdiff
path: root/testcode/streamtcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'testcode/streamtcp.c')
-rw-r--r--testcode/streamtcp.c69
1 files changed, 60 insertions, 9 deletions
diff --git a/testcode/streamtcp.c b/testcode/streamtcp.c
index 497e3d2888fe..668d6360bb9a 100644
--- a/testcode/streamtcp.c
+++ b/testcode/streamtcp.c
@@ -73,6 +73,7 @@ static void usage(char* argv[])
printf("-f server what ipaddr@portnr to send the queries to\n");
printf("-u use UDP. No retries are attempted.\n");
printf("-n do not wait for an answer.\n");
+ printf("-a print answers as they arrive.\n");
printf("-d secs delay after connection before sending query\n");
printf("-s use ssl\n");
printf("-h this help text\n");
@@ -203,13 +204,22 @@ recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf)
uint16_t len;
if(!udp) {
if(ssl) {
- if(SSL_read(ssl, (void*)&len, (int)sizeof(len)) <= 0) {
+ int sr = SSL_read(ssl, (void*)&len, (int)sizeof(len));
+ if(sr == 0) {
+ printf("ssl: stream closed\n");
+ exit(1);
+ }
+ if(sr < 0) {
log_crypto_err("could not SSL_read");
exit(1);
}
} else {
- if(recv(fd, (void*)&len, sizeof(len), 0) <
- (ssize_t)sizeof(len)) {
+ ssize_t r = recv(fd, (void*)&len, sizeof(len), 0);
+ if(r == 0) {
+ printf("recv: stream closed\n");
+ exit(1);
+ }
+ if(r < (ssize_t)sizeof(len)) {
#ifndef USE_WINSOCK
perror("read() len failed");
#else
@@ -267,6 +277,37 @@ recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf)
free(pktstr);
}
+/** see if we can receive any results */
+static void
+print_any_answers(int fd, int udp, SSL* ssl, sldns_buffer* buf,
+ int* num_answers, int wait_all)
+{
+ /* see if the fd can read, if so, print one answer, repeat */
+ int ret;
+ struct timeval tv, *waittv;
+ fd_set rfd;
+ while(*num_answers > 0) {
+ memset(&rfd, 0, sizeof(rfd));
+ memset(&tv, 0, sizeof(tv));
+ FD_ZERO(&rfd);
+ FD_SET(fd, &rfd);
+ if(wait_all) waittv = NULL;
+ else waittv = &tv;
+ ret = select(fd+1, &rfd, NULL, NULL, waittv);
+ if(ret < 0) {
+ if(errno == EINTR || errno == EAGAIN) continue;
+ perror("select() failed");
+ exit(1);
+ }
+ if(ret == 0) {
+ if(wait_all) continue;
+ return;
+ }
+ (*num_answers) -= 1;
+ recv_one(fd, udp, ssl, buf);
+ }
+}
+
static int get_random(void)
{
int r;
@@ -278,12 +319,12 @@ static int get_random(void)
/** send the TCP queries and print answers */
static void
-send_em(const char* svr, int udp, int usessl, int noanswer, int delay,
- int num, char** qs)
+send_em(const char* svr, int udp, int usessl, int noanswer, int onarrival,
+ int delay, int num, char** qs)
{
sldns_buffer* buf = sldns_buffer_new(65553);
int fd = open_svr(svr, udp);
- int i;
+ int i, wait_results = 0;
SSL_CTX* ctx = NULL;
SSL* ssl = NULL;
if(!buf) fatal_exit("out of memory");
@@ -325,9 +366,15 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int delay,
write_q(fd, udp, ssl, buf, (uint16_t)get_random(), qs[i],
qs[i+1], qs[i+2]);
/* print at least one result */
- if(!noanswer)
+ if(onarrival) {
+ wait_results += 1; /* one more answer to fetch */
+ print_any_answers(fd, udp, ssl, buf, &wait_results, 0);
+ } else if(!noanswer) {
recv_one(fd, udp, ssl, buf);
+ }
}
+ if(onarrival)
+ print_any_answers(fd, udp, ssl, buf, &wait_results, 1);
if(usessl) {
SSL_shutdown(ssl);
@@ -368,6 +415,7 @@ int main(int argc, char** argv)
const char* svr = "127.0.0.1";
int udp = 0;
int noanswer = 0;
+ int onarrival = 0;
int usessl = 0;
int delay = 0;
@@ -394,11 +442,14 @@ int main(int argc, char** argv)
if(argc == 1) {
usage(argv);
}
- while( (c=getopt(argc, argv, "f:hnsud:")) != -1) {
+ while( (c=getopt(argc, argv, "af:hnsud:")) != -1) {
switch(c) {
case 'f':
svr = optarg;
break;
+ case 'a':
+ onarrival = 1;
+ break;
case 'n':
noanswer = 1;
break;
@@ -446,7 +497,7 @@ int main(int argc, char** argv)
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
#endif
}
- send_em(svr, udp, usessl, noanswer, delay, argc, argv);
+ send_em(svr, udp, usessl, noanswer, onarrival, delay, argc, argv);
checklock_stop();
#ifdef USE_WINSOCK
WSACleanup();