[netperf-dev] netperf4 commit notice r28 - trunk/src

raj at netperf.org raj at netperf.org
Wed Nov 30 16:23:59 PST 2005


Author: raj
Date: 2005-11-30 16:23:58 -0800 (Wed, 30 Nov 2005)
New Revision: 28

Modified:
   trunk/src/dns_commands.xml
   trunk/src/dns_config.xml
   trunk/src/netlib.c
   trunk/src/netlib.h
   trunk/src/nettest_dns.c
   trunk/src/nettest_dns.h
Log:
Implement multiple outstanding DNS requests per thread, and modularize a bit.
Also add a delta_milli to go with delta_micro to make life easier for checking
timeouts.


Modified: trunk/src/dns_commands.xml
===================================================================
--- trunk/src/dns_commands.xml	2005-11-30 01:00:36 UTC (rev 27)
+++ trunk/src/dns_commands.xml	2005-12-01 00:23:58 UTC (rev 28)
@@ -6,7 +6,7 @@
  eg dns_config.xml or whatever you may want to use -->
 
   <!-- cause a set of tests to be instantiated -->
-  <create_test_set set_name="s0" tests_in_set="t0,t1" />
+  <create_test_set set_name="s0" tests_in_set="t0" />
   <wait tid="s0" />
   <!-- now ask that all the tests in the set go to the load state -->
   <load tid="s0" />
@@ -17,9 +17,7 @@
   <load tid="s0" />
   <wait tid="s0" />
   <get_stats tid="t0" />
-  <get_stats tid="t1" />
   <clear_stats tid="t0" />
-  <clear_stats tid="t1" />
   <idle tid="s0" />
   <wait tid="s0" />
   <report_stats test_set="s0" 

Modified: trunk/src/dns_config.xml
===================================================================
--- trunk/src/dns_config.xml	2005-11-30 01:00:36 UTC (rev 27)
+++ trunk/src/dns_config.xml	2005-12-01 00:23:58 UTC (rev 28)
@@ -5,10 +5,6 @@
 <netserver nid="n1" >
   <!-- within the netserver there can be several "test" entities -->
   <test tid="t0"
-    test_name = "sys_stats"
-    library   = "netsysstats.la" >
-  </test>
-  <test tid="t1"
     test_name = "send_dns_rr"
     library   = "nettest_dns.la" >
     <!-- The dependency data section gives the info for the DNS server -->
@@ -20,8 +16,7 @@
       recv_buffer_size = "128" />
     <dns_args
     	max_outstanding = "1"
-	timeout         = "5000" 
-        use_tcp         = "false" />
+	timeout         = "5000" />
   </test>
 </netserver>
 </netperf>

Modified: trunk/src/netlib.c
===================================================================
--- trunk/src/netlib.c	2005-11-30 01:00:36 UTC (rev 27)
+++ trunk/src/netlib.c	2005-12-01 00:23:58 UTC (rev 28)
@@ -52,6 +52,10 @@
 #include <string.h>
 #endif
 
+#ifdef HAVE_STRINGS_H
+#include <strings.h>
+#endif
+
 #ifdef HAVE_SYS_SOCKET_H
 #include <sys/socket.h>
 #endif
@@ -103,11 +107,20 @@
 int
 delta_micro(hrtime_t *begin, hrtime_t *end)
 {
-  long nsecs;
+  int64_t nsecs;
   nsecs = (*end) - (*begin);
   return(nsecs/1000);
 }
 
+int
+delta_milli(hrtime_t *begin, hrtime_t *end)
+{
+  int64_t nsecs;
+  nsecs = (*end) - (*begin);
+  return(nsecs/1000000);
+}
+
+
 #else
 
 void
@@ -138,6 +151,28 @@
   return(usecs);
 
 }
+ /* return the difference (in milliseconds) between two timeval
+    timestamps */
+int
+delta_milli(struct timeval *begin,struct timeval *end)
+
+{
+
+  int usecs, secs;
+
+  if (end->tv_usec < begin->tv_usec) {
+    /* borrow a second from the tv_sec */
+    end->tv_usec += 1000000;
+    end->tv_sec--;
+  }
+  usecs = end->tv_usec - begin->tv_usec;
+  secs  = end->tv_sec - begin->tv_sec;
+
+  usecs += (secs * 1000000);
+
+  return(usecs/1000);
+
+}
 #endif /* HAVE_GETHRTIME */
 
 /* This routine will return the two arguments to the calling routine. */

Modified: trunk/src/netlib.h
===================================================================
--- trunk/src/netlib.h	2005-11-30 01:00:36 UTC (rev 27)
+++ trunk/src/netlib.h	2005-12-01 00:23:58 UTC (rev 28)
@@ -41,7 +41,7 @@
 extern  void report_test_status(server_t *server);
 extern  GenReport get_report_function(xmlNodePtr cmd);
 
-
+/* do we REALLY want this stuff? */
 #ifdef NO_DLOPEN
 #include <dl.h>
 

Modified: trunk/src/nettest_dns.c
===================================================================
--- trunk/src/nettest_dns.c	2005-11-30 01:00:36 UTC (rev 27)
+++ trunk/src/nettest_dns.c	2005-12-01 00:23:58 UTC (rev 28)
@@ -270,8 +270,8 @@
       my_data->use_tcp = 0;
     }
     else {
-      if (!strcasecmp(string,"true") ||
-	  !strcasecmp(string,"yes")) {
+      if (!strcasecmp((char *)string,"true") ||
+	  !strcasecmp((char *)string,"yes")) {
 	hints.ai_socktype = SOCK_STREAM;
 	hints.ai_protocol = IPPROTO_TCP;
 	my_data->use_tcp = 1;
@@ -681,7 +681,7 @@
 			    sure we don't overflow these things on the
 			    fscanf... */
   char temp_type[64];
-  char temp_success[64];
+  int temp_success;
 
   if (my_data->request_source) {
     /* ah, good, we do have a file */
@@ -690,14 +690,14 @@
 	       temp_name,
 	       temp_class,
 	       temp_type,
-	       temp_success) == EOF) {
+	       &temp_success) == EOF) {
       rewind(my_data->request_source);
       if (fscanf(my_data->request_source,
 		 "%s %s %s %d\n",
 		 temp_name,
 		 temp_class,
 		 temp_type,
-		 temp_success) == EOF) {
+		 &temp_success) == EOF) {
 	/* something like that should never happen */
 	return(-1);
       }
@@ -727,7 +727,7 @@
 			    sure we don't overflow these things on the
 			    fscanf... */
   char temp_type[64];
-  char temp_success[64];
+  int  temp_success;
   
   struct timeval foo;
   int i;
@@ -744,7 +744,7 @@
 		 temp_name,
 		 temp_class,
 		 temp_type,
-		 temp_success) == EOF) {
+		 &temp_success) == EOF) {
 	rewind(my_data->request_source);
       }
     }
@@ -757,6 +757,7 @@
 {
   dns_data_t *new_data;
   xmlNodePtr  args;
+  xmlNodePtr  socket_args = NULL;
   xmlNodePtr  dns_args = NULL;
   xmlChar    *string;
   xmlChar    *units;
@@ -774,22 +775,24 @@
   new_data = (dns_data_t *)malloc(sizeof(dns_data_t));
 
   args = test->node->xmlChildrenNode;
+  /* make sure we go though everything, and do not assume anything
+     about the order of the elements. raj 2005-11-30 */
   while (args != NULL) {
+    printf("NAME %s\n",args->name);
     if (!xmlStrcmp(args->name,(const xmlChar *)"dependency_data")) {
       test->dependency_data = args;
     }
-    if (!xmlStrcmp(args->name,(const xmlChar *)"dns_args")) {
+    else if (!xmlStrcmp(args->name,(const xmlChar *)"dns_args")) {
       dns_args = args;
     }
-    if (xmlStrcmp(args->name,(const xmlChar *)"socket_args")) {
-      args = args->next;
-      continue;
+    else if (!xmlStrcmp(args->name,(const xmlChar *)"socket_args")) {
+      socket_args = args;
     } 
-    break;
+    args = args->next;
   }
- 
+  
   /* probably a good idea to make sure that new_data is real */
-  if ((args != NULL) &&
+  if ((socket_args != NULL) &&
       (NULL != new_data)) {
     /* zero the dns test specific data structure */
     test_specific_data_init(new_data);
@@ -797,7 +800,7 @@
     /* while we are not using it as a means to fill buffers with data,
        we do use "fill_file" as the way to tell where the list of
        dns_requests happen to be */
-    string =  xmlGetProp(args,(const xmlChar *)"fill_file");
+    string =  xmlGetProp(socket_args,(const xmlChar *)"fill_file");
     /* fopen the fill file it will be used when finding work to do */
     if (string) {
       new_data->request_source = fopen((char *)string,"r");
@@ -807,12 +810,12 @@
     /* we are relying on the good graces of the validating and
        attribute filling of libxml when we parsed the message that got
        us here... */
-    string =  xmlGetProp(args,(const xmlChar *)"send_buffer_size");
-    units  =  xmlGetProp(args,(const xmlChar *)"send_buffer_units");
+    string =  xmlGetProp(socket_args,(const xmlChar *)"send_buffer_size");
+    units  =  xmlGetProp(socket_args,(const xmlChar *)"send_buffer_units");
     new_data->send_buf_size = convert(string,units);
 
-    string =  xmlGetProp(args,(const xmlChar *)"recv_buffer_size");
-    units  =  xmlGetProp(args,(const xmlChar *)"recv_buffer_units");
+    string =  xmlGetProp(socket_args,(const xmlChar *)"recv_buffer_size");
+    units  =  xmlGetProp(socket_args,(const xmlChar *)"recv_buffer_units");
     new_data->recv_buf_size = convert(string,units);
 
     /* we need to add code somewhere here to get stuff such as whether
@@ -820,7 +823,7 @@
        open... */
 
     /* now get and initialize the local addressing info */
-    string   =  xmlGetProp(args,(const xmlChar *)"family");
+    string   =  xmlGetProp(socket_args,(const xmlChar *)"family");
     localfam = strtofam(string);
     memset(&hints, 0, sizeof(hints));
     hints.ai_family   = localfam;
@@ -828,8 +831,8 @@
     hints.ai_protocol = protocol;
     hints.ai_flags    = 0;
 
-    localhost = xmlGetProp(args,(const xmlChar *)"local_host"),
-    localport = xmlGetProp(args,(const xmlChar *)"local_service"),
+    localhost = xmlGetProp(socket_args,(const xmlChar *)"local_host"),
+    localport = xmlGetProp(socket_args,(const xmlChar *)"local_service"),
     count = 0;
     do {
       error = getaddrinfo( (char *)localhost, (char *)localport,
@@ -871,16 +874,18 @@
                           gai_strerror(error));
     }
     if (dns_args) {
-      string =  xmlGetProp(args,(const xmlChar *)"max_outstanding");
+      string =  xmlGetProp(dns_args,(const xmlChar *)"max_outstanding");
       if (string) {
-	new_data->max_outstanding = atoi(string);
+	printf("GOT max_outstanding\n");
+	new_data->max_outstanding = atoi((char *)string);
       }
       else {
+	printf("NO max_outstanding\n");
 	new_data->max_outstanding = 1;
       }
-      string =  xmlGetProp(args,(const xmlChar *)"timeout");
+      string =  xmlGetProp(dns_args,(const xmlChar *)"timeout");
       if (string) {
-	new_data->timeout = atoi(string);
+	new_data->timeout = atoi((char *)string);
       }
       else {
 	new_data->timeout = 5000;
@@ -889,6 +894,7 @@
     else {
       /* there was no dns_args element in the test element, so use the
 	 program defaults. raj 2005-11-29 */
+      printf("NO dns_args\n");
       new_data->max_outstanding = 1;
       new_data->timeout = 5000;
     }
@@ -1132,6 +1138,239 @@
   }
 }
 
+
+/* return the the next available free status entry.  if none exist,
+   return NULL. raj 2005-11-30. question - should we also be checking
+   for requests which have timed-out? why not...it might be the way we
+   get a free entry. however, we won't scan the entire thing just to
+   check all the  */
+
+static dns_request_status_t *
+get_free_status_entry(test_t *test) {
+  dns_request_status_t *temp;
+  dns_request_status_t *free;
+  int                   count;
+  dns_data_t           *my_data;
+  NETPERF_TIMESTAMP_T   now;
+
+  free = NULL;
+  my_data = GET_TEST_DATA(test);
+  netperf_timestamp(&now);
+
+  /* we ass-u-me that max_outstanding is never so large that just a
+     simplistic linear search is heinous.  famous last words :) raj
+     2005-11-30 */ 
+  for (count = 0; 
+       (NULL == free) && (count < my_data->max_outstanding);
+       count++) {
+    temp = &(my_data->outstanding_requests[count]);
+    if (temp->active) {
+      if (delta_milli(&(temp->sent_time),&now) >= my_data->timeout) {
+	if (test->debug) {
+	  fprintf(test->where,
+		  "EXPIRING message %d in %s after %d ms\n",
+		  temp->id,
+		  __func__,
+		  delta_milli(&(temp->sent_time),&now));
+	  fflush(test->where);
+	}
+	memset(temp,0,sizeof(dns_request_status_t));
+	my_data->num_outstanding--;
+	free = temp;
+      }
+    }
+    else {
+      free = temp;
+    }
+  }
+  return(free);
+}
+
+/* find a status entry matching the specified message_id.  while we
+   are cruising through the list, we migh as well look for expired
+   entries. raj 2005-11-30 */
+
+static dns_request_status_t *
+find_status_entry(test_t *test, uint16_t message_id) {
+  dns_request_status_t *temp;
+  dns_request_status_t *match;
+  int                   count;
+  dns_data_t           *my_data;
+  NETPERF_TIMESTAMP_T   now;
+
+  match = NULL;
+  my_data = GET_TEST_DATA(test);
+  netperf_timestamp(&now);
+
+  /* we ass-u-me that max_outstanding is never so large that just a
+     simplistic linear search is heinous.  famous last words :) raj
+     2005-11-30 */ 
+  for (count = 0; 
+       (NULL == match) && (count < my_data->max_outstanding);
+       count++) {
+    temp = &(my_data->outstanding_requests[count]);
+    if (temp->active) {
+      /* it is an active entry, is it a match ?*/
+      if (temp->id == message_id) {
+	/* we match, so no matter what we will decrement the count of
+	   outstanding requests, but is it expired? */
+	if (delta_milli(&(temp->sent_time),&now) >= my_data->timeout){
+	  printf("EXPIRING message %d in %s\n",temp->id, __func__);
+	  memset(temp,0,sizeof(dns_request_status_t));
+	}
+	else {
+	  match = temp;
+	}
+	my_data->num_outstanding--;
+      }
+      else {
+	/* didn't match, but is it expired, be sure to watch the sense
+	   of the comparison */
+	if (delta_milli(&(temp->sent_time),&now) >= my_data->timeout){
+	  if (test->debug) {
+	    fprintf(test->where,
+		    "EXPIRING message %d from %s after %d ms\n",
+		    temp->id,
+		    __func__,
+		    delta_milli(&(temp->sent_time),&now));
+	    fflush(test->where);
+	  }
+	  memset(temp,0,sizeof(dns_request_status_t));
+	  my_data->num_outstanding--;
+	}
+      }
+    }
+  }
+  return(match);
+}
+
+/* walk the list of entries, looking for those that have expired */
+static void
+scan_for_expired_requests(test_t *test) {
+  dns_request_status_t *temp;
+  int                   count;
+  dns_data_t           *my_data;
+  NETPERF_TIMESTAMP_T   now;
+
+  my_data = GET_TEST_DATA(test);
+  netperf_timestamp(&now);
+
+  /* we ass-u-me that max_outstanding is never so large that just a
+     simplistic linear search is heinous.  famous last words :) raj
+     2005-11-30 */ 
+  for (count = 0; 
+       (count < my_data->max_outstanding);
+       count++) {
+    temp = &(my_data->outstanding_requests[count]);
+    if ((temp->active) && 
+	(delta_milli(&(temp->sent_time),&now) >= my_data->timeout)) {
+      if (test->debug) {
+	fprintf(test->where,
+		"EXPIRING message %d from %s after %d ms\n",
+		temp->id,
+		__func__,
+		delta_milli(&(temp->sent_time),&now));
+	fflush(test->where);
+      }
+      memset(temp,0,sizeof(dns_request_status_t));
+      my_data->num_outstanding--;
+    }
+  }
+}
+
+/* send at most max_outstanding requests onto the network, return
+   errors as appropriate - either -1 if something went wrong, or the
+   number of requests sent, which could be zero.  if we ever go
+   non-blocking on the socket, we may need to be a bit more
+   sophisticated in our error checking and send calls - especially if
+   we ever start using TCP. raj 2005-11-30 */
+static int
+send_dns_requests(test_t *test) 
+{
+  dns_data_t  *my_data;
+  int          sent = 0;
+  int          req_size;
+  int          len;
+  uint16_t     request_buffer[NS_PACKETSZ/sizeof(uint16_t)];  
+  uint16_t     message_id;
+
+  dns_request_status_t *status_entry;
+
+  my_data = GET_TEST_DATA(test);
+
+  while (my_data->num_outstanding < my_data->max_outstanding ) {
+    printf("MAX %d OUTSTANDING %d\n",my_data->max_outstanding,
+	   my_data->num_outstanding);
+    /* go through and build the next request to send */
+    req_size = get_next_dns_request(test, 
+				    (char *)request_buffer, 
+				    sizeof(request_buffer));
+      
+    /* set the ID as apropriate since it is a uint16_t, we'll not
+       worry about "overflow" as it will just be dealt with
+       "naturally. we use the magic number of "0" based on "knowing"
+       that the ID is the first thing in the message, and it seems
+       there is no commonly defined structure for a DNS reqeust
+       header?  raj 2005-11-18 */
+      
+    message_id = request_buffer[0] = my_data->request_id++; 
+
+    if (test->debug) {
+      fprintf(test->where,
+	      "SENDING message %d\n",
+	      message_id);
+      fflush(test->where);
+    }
+    /* now stash some state away so we can deal with the response */
+    status_entry = get_free_status_entry(test);
+    if (status_entry) {
+      status_entry->active = 1;
+      status_entry->success = 1;
+      netperf_timestamp(&(status_entry->sent_time));
+      status_entry->id = message_id;
+    }
+    else {
+      /* this could be bad?  or is it just an expired entry? */
+      printf("Hey dummy, there were no free status entries!\n");
+      return(-1);
+    }
+    /* send data for the test. we can use send() rather than
+       sendto() because in _init we will have called connect() on
+       the socket.  now, if we are using UDP and the server happens
+       to reply from a source IP address other than the one to which
+       we have connected... well...  raj 2005-11-18 */
+      
+    /* if we are ever going to _really_ pace these things, we need
+       logic to decide if it is time to send another request or
+       not */
+      
+    if((len=send(my_data->query_socket,
+		 request_buffer,
+		 req_size,
+		 0)) != req_size) {
+      /* this macro hides Windows differences */
+      if (CHECK_FOR_SEND_ERROR(len)) {
+	report_test_failure(test,
+			    __func__,
+			    DNSE_DATA_SEND_ERROR,
+			    "data send error");
+	/* do we need to do something additional here? probably */
+	return(-1);
+      }
+    }
+    /* my_data->stats.named.queries_sent++; */
+    /* my_data->stats.named.query_bytes_sent += len; */
+    my_data->num_outstanding++;
+    sent++;
+  }
+  return(sent);
+}
+
+static int
+recv_dns_responses(test_t *test)
+{
+}
+
 static uint32_t
 send_dns_rr_meas(test_t *test)
 {
@@ -1167,59 +1406,18 @@
 
   while (NO_STATE_CHANGE(test) &&
 	 keep_going) {
-    while (my_data->num_outstanding < my_data->max_outstanding ) {
-      /* go through and build the next request to send */
-      req_size = get_next_dns_request(test, 
-				      (char *)request_buffer, 
-				      sizeof(request_buffer));
-      
-      /* set the ID as apropriate since it is a uint16_t, we'll not
-	 worry about "overflow" as it will just be dealt with
-	 "naturally. we use the magic number of "0" based on "knowing"
-	 that the ID is the first thing in the message, and it seems
-	 there is no commonly defined structure for a DNS reqeust
-	 header?  raj 2005-11-18 */
-      
-      message_id = request_buffer[0] = my_data->request_id++; 
-      
-      /* now stash some state away so we can deal with the response */
-      status_entry = &(my_data->outstanding_requests[message_id]);
-      if (status_entry->active) {
-	/* this could be bad?  or is it just an expired entry? */
-	printf("Hey dummy, this entry %d is already active!\n",message_id);
-      }
-      else {
-	status_entry->active = 1;
-	status_entry->success = 1;
-	netperf_timestamp(&(status_entry->sent_time));
-      }
-      /* send data for the test. we can use send() rather than
-	 sendto() because in _init we will have called connect() on
-	 the socket.  now, if we are using UDP and the server happens
-	 to reply from a source IP address other than the one to which
-	 we have connected... well...  raj 2005-11-18 */
-      
-      /* if we are ever going to _really_ pace these things, we need
-	 logic to decide if it is time to send another request or
-	 not */
-      
-      if((len=send(my_data->query_socket,
-		   request_buffer,
-		   req_size,
-		   0)) != req_size) {
-	/* this macro hides windows differences */
-	if (CHECK_FOR_SEND_ERROR(len)) {
-	  keep_going = 0;
-	  report_test_failure(test,
-			      __func__,
-			      DNSE_DATA_SEND_ERROR,
-			      "data send error");
-	}
-      }
-      /* my_data->stats.named.queries_sent++; */
-      /* my_data->stats.named.query_bytes_sent += len; */
-      my_data->num_outstanding++;
+    /* this will put as many requests out there as we are allowed to
+       have, and tell us how many it sent.  one of these days, we will
+       start tracking how many we sent in addition to how many
+       completed. */
+    ret = send_dns_requests(test);
+    if (ret < 0) {
+      /* if something bad happened, we likely don't want to try to
+	 poll */
+      keep_going = 0;
+      continue;
     }
+
     /* recv the request for the test, but first we really need some sort
        of timeout on a poll call or whatnot... */
 
@@ -1227,6 +1425,10 @@
     fds.events = POLLIN;
     fds.revents = 0;
 
+    /* I wonder if we want a different (presumably smaller) poll
+       timeout from the DNS request timeout, if for no other reason
+       than to make the test a triffle more responsive to state
+       changes? raj 2005-11-30 */
     ret = poll(&fds,1,my_data->timeout);
 
     switch (ret) {
@@ -1240,30 +1442,21 @@
     
       break;
     case 0:
+      if (test->debug) {
+	fprintf(test->where,
+		"TIMEOUT in %s num_outstanding %d\n",
+		__func__,
+		my_data->num_outstanding);
+	fflush(test->where);
+      }
       /* we had a timeout. invalidate the existing request(s) as
-	 apropriate so we will ignore it if it was simply
-	 delayed. status_entry should still be valid.  we only need to
-	 go back at most num_outstanding requests */
-      num_to_check = my_data->num_outstanding;
-      netperf_timestamp(&now);
-      message_id = my_data->request_id;
-      message_id--;   /* my_data->request_id is actually one more than
-			 we sent */
-      while (num_to_check) {
-	status_entry = &(my_data->outstanding_requests[message_id]);
-	if ((status_entry->active) &&
-	    (delta_micro(&(status_entry->sent_time),&now) >= 
-	     my_data->timeout * 1000)) {
-	  my_data->num_outstanding--;
-	  memset(status_entry,0,sizeof(status_entry));
-	}
-	message_id--;  /* wrap-around is handled automagically since
-			  this is a uint16_t */
-	num_to_check--;
-      }
+	 appropriate so we will ignore it if it was simply delayed.
+	 status_entry should still be valid.  we only need to go back
+	 at most num_outstanding requests */
+      scan_for_expired_requests(test);
       break;
     case 1:
-  
+      /* there is actually something there to recv :) */
       bytes_left = NS_PACKETSZ; /* we'll do something clever inside the
 				   loop to handle UDP vs TCP. */
       rsp_ptr = request_buffer;  /* until we discover it is a bug, re-use
@@ -1300,28 +1493,46 @@
 	}
       }
       response_id = rsp_ptr[0];
-      status_entry  = &(my_data->outstanding_requests[response_id]);
-      if (status_entry->active) {
+      status_entry  = find_status_entry(test, response_id);
+
+      if ((status_entry) &&
+	  (status_entry->active)) {
+	if (test->debug) {
+	  NETPERF_TIMESTAMP_T now;
+	  netperf_timestamp(&now);
+	  fprintf(test->where,
+		  "COMPLETING message %d in %s after %d ms\n",
+		  response_id,
+		  __func__,
+		  delta_milli(&(status_entry->sent_time),&now));
+	  fflush(test->where);
+	}
+
 	/* this is what we want to see */
 	/* code to timestamp enabled by HISTOGRAM */
 	HIST_TIMESTAMP(&time_two);
 	HIST_ADD(my_data->time_hist,
-		 delta_micro(&(status_entry->sent_time),&time_two));
+		 delta_milli(&(status_entry->sent_time),&time_two));
 	/* my_data->stats.named.responses_received++; */
 	/* so we can continue to "leverage" the nettest_bsd reporter for
 	   now. raj 2005-11-18 */
-	my_data->num_outstanding--;
 	my_data->stats.named.trans_sent++;
 	my_data->stats.named.trans_received++;
 	/* my_data->stats.named.response_bytes_received += response_len; */
 	/* hey dummy, don't forget to clear the entry... raj 2005-11-22 */
-	memset(status_entry,0,sizeof(status_entry));
+	memset(status_entry,0,sizeof(dns_request_status_t));
       }
       else {
 	/* is this bad?  well, if we were in a transition from LOAD to
 	   MEAS state it could happen I suppose so for now we will simply
 	   ignore the message */
-	printf("Yo! no match on request_id, entry inactive\n");
+	if (test->debug) {
+	  fprintf(test->where,
+		  "IGNORING message %d in %s entry inactive or not present\n",
+		  response_id,
+		  __func__);
+	  fflush(test->where);
+	}
       }
 
       if (len == 0) {
@@ -1355,16 +1566,13 @@
   int               len;
   int               bytes_left;
   int               req_size;
-  char             *rsp_ptr;
+  uint16_t         *rsp_ptr;
   dns_data_t       *my_data;
   struct pollfd     fds;
   int               keep_going=1;
-  char              request_buffer[NS_PACKETSZ];  /* that aught to be
-						     enough to hold it
-						     - modulo stuff
-						     like large
-						     requests on TCP
-						     connections... */
+  uint16_t          response_id;
+  dns_request_status_t *status_entry;
+  uint16_t           request_buffer[NS_PACKETSZ/sizeof(uint16_t)];
 
   NETPERF_DEBUG_ENTRY(test->debug,test->where);
 
@@ -1372,27 +1580,15 @@
 
   while (NO_STATE_CHANGE(test) &&
 	 keep_going) {
-    /* go through and build the next request to send */
-    req_size = get_next_dns_request(test, 
-				    request_buffer, 
-				    sizeof(request_buffer));
 
+    ret = send_dns_requests(test);
+    if (ret < 0) {
+      /* if something bad happened, we likely don't want to try to
+	 poll */
+      keep_going = 0;
+      continue;
+    }
 
-    /* send data for the test */
-    if((len=send(my_data->query_socket,
-		 request_buffer,
-		 req_size,
-		 0)) != req_size) {
-      /* this macro hides windows differences */
-      if (CHECK_FOR_SEND_ERROR(len)) {
-	keep_going = 0;
-	report_test_failure(test,
-			    __func__,
-			    DNSE_DATA_SEND_ERROR,
-			    "data send error");
-      }
-    }
-  
     fds.fd = my_data->query_socket;
     fds.events = POLLIN;
     fds.revents = 0;
@@ -1410,8 +1606,15 @@
     
       break;
     case 0:
-      /* we had a timeout. since we are not actually measuring anything,
-	 there is no status_entry to update. raj 2005-11-18 */
+      /* we had a timeout. */
+      if (test->debug) {
+	fprintf(test->where,
+		"TIMEOUT in %s num_outstanding %d\n",
+		__func__,
+		my_data->num_outstanding);
+	fflush(test->where);
+      }
+      scan_for_expired_requests(test);
       break;
     case 1:
       /* recv the request for the test */
@@ -1437,11 +1640,11 @@
 	    bytes_left = 0;
 	  }
 	  else {
-	    /* not quite sure what to do here - probably have to parse the
-	       packet a bit more */
+	    /* not quite sure what to do here - probably have to parse
+	       the packet a bit more, but that will happen once we
+	       support sending requests over TCP, for UDP, we should
+	       never really get here*/
 	  }
-	  rsp_ptr    += len;
-	  bytes_left -= len;
 	}
 	else {
 	  /* len is 0 the connection was closed exit the while loop */
@@ -1449,6 +1652,41 @@
 	  break;
 	}
       }
+
+      response_id = rsp_ptr[0];
+      status_entry  = find_status_entry(test, response_id);
+
+      if ((status_entry) &&
+	  (status_entry->active)) {
+	if (test->debug) {
+	  NETPERF_TIMESTAMP_T now;
+	  netperf_timestamp(&now);
+	  fprintf(test->where,
+		  "COMPLETING message %d in %s after %d ms\n",
+		  response_id,
+		  __func__,
+		  delta_milli(&(status_entry->sent_time),&now));
+	  fflush(test->where);
+	}
+
+	/* since we are in the load state we do not actually record
+	   any completed transactions, just go ahead and clear the
+	   status_entry. raj 2005-11-30 */
+	memset(status_entry,0,sizeof(dns_request_status_t));
+      }
+      else {
+	/* is this bad?  well, if we were in a transition from LOAD to
+	   MEAS state it could happen I suppose so for now we will simply
+	   ignore the message */
+	if (test->debug) {
+	  fprintf(test->where,
+		  "IGNORING message %d in %s entry inactive or not present\n",
+		  response_id,
+		  __func__);
+	  fflush(test->where);
+	}
+      }
+
       break;
 
     }

Modified: trunk/src/nettest_dns.h
===================================================================
--- trunk/src/nettest_dns.h	2005-11-30 01:00:36 UTC (rev 27)
+++ trunk/src/nettest_dns.h	2005-12-01 00:23:58 UTC (rev 28)
@@ -57,7 +57,8 @@
 typedef struct dns_request_status {
   unsigned short active; /* was there a query sent with this id for
 		 which we are awaiting a response */
-  unsigned short success; /* should the request have been successful
+  uint16_t       id;
+  int32_t        success; /* should the request have been successful
 			     or not */
   NETPERF_TIMESTAMP_T sent_time;
 } dns_request_status_t;



More information about the netperf-dev mailing list