--- deadwood-2.9.06/src/DwHash.c	2010-09-03 07:03:38.000000000 -0700
+++ deadwood-2.9.07/src/DwHash.c	2010-09-08 18:26:17.000000000 -0700
@@ -23,15 +23,15 @@
 #include "DwSys.h"
 #include <stdint.h>
 #include <stdio.h> /* For reading and writing the hash to a file */
+#include <time.h>
 
 #include "DwHash.h"
 /* The default value for the multiply constant is a 31-bit random prime
  * number; this number is generated by the RandomPrime program, whose
  * output is the file DwRandPrime.h */
 #include "DwRandPrime.h"
-#ifndef MUL_CONSTANT
-#define MUL_CONSTANT magic_number
-#endif /* MUL_CONSTANT */
+
+uint32_t add_constant = 0x74fc65a2;
 
 /* Mararc (OK, dwood2rc) parameters that are set in DwMararc.c */
 extern int32_t key_n[];
@@ -45,7 +45,60 @@
 /* Functions for hashing DwStr objects, and using said hash to store
  * information in a table */
 
-/* Set global variables based on dwood2rc parameters */
+/* Called before reading dwood3rc, this sets add_constant based on
+ * secret.txt in Windows and /dev/urandom in Unix */
+void set_add_constant() {
+	FILE *in = 0;
+	dwr_rg *quick_n_dirty = 0;
+	dw_str *seedit = 0;
+	int counter = 0;
+	time_t timestamp = 0;
+
+#ifdef MINGW
+	in = fopen("secret.txt","rb");
+#else
+	in = fopen("/dev/urandom","rb");
+#endif /* MINGW */
+
+	if(in == 0) { 
+		goto catch_set_add_constant;
+	}
+
+	seedit = dw_create(14);
+
+	if(seedit == 0) {
+		goto catch_set_add_constant;
+	}
+
+	seedit->len = 11;
+	for(counter = 0; counter < 8; counter++) {
+		*(seedit->str + counter) = getc(in);
+	}
+	timestamp = time(0);
+	*(seedit->str + 8) = (timestamp & 0xff);
+	*(seedit->str + 9) = (timestamp & 0xff00) >> 8;
+	*(seedit->str + 10) = (timestamp & 0xff0000) >> 16;
+
+	quick_n_dirty = dwr_init_rg(seedit);
+	dw_destroy(seedit);
+	if(quick_n_dirty == 0) {
+		goto catch_set_add_constant;
+	}
+
+	add_constant ^= dwr_rng(quick_n_dirty);
+	add_constant ^= (dwr_rng(quick_n_dirty) << 15);
+	dwr_zap(quick_n_dirty);
+
+	return;
+
+catch_set_add_constant:	
+#ifndef MINGW
+	printf("Warning: Can not set add_constant\n");
+#endif
+	return; 
+}
+			
+/* Set global variables based on dwood3rc parameters */
 void dwh_process_mararc_params() {
         int32_t possible_magic_number;
 
@@ -55,8 +108,9 @@
          * dwood2rc this way */
         possible_magic_number = key_n[DWM_N_hash_magic_number];
         if(possible_magic_number > 0x40000000) {
-                magic_number = possible_magic_number;
+		dw_log_string("Warning: hash_magic_number disabled",0);
         }
+	dw_log_hex("add_constant is set to 0x",add_constant,10);
 
 }
 
@@ -95,12 +149,14 @@
                 /* Done getting 4 bytes from string */
                 out ^= tmp;
                 out *= MUL_CONSTANT;
+		out += add_constant;
                 out = (out >> 19) | (out << 13);
                 offset += 4;
         }
 
         out ^= obj->len;
         out *= MUL_CONSTANT;
+	out += add_constant;
         out = (out >> 19) | (out << 13);
 
 #ifdef HASH_DEBUG
--- deadwood-2.9.06/src/RandomPrime.c	2010-09-03 07:03:38.000000000 -0700
+++ deadwood-2.9.07/src/RandomPrime.c	2010-09-08 18:26:17.000000000 -0700
@@ -23,15 +23,7 @@
 /* A header that can be included by DwHash.c */
 #define HEADER "/* This file is automatically generated by RandomPrime */\n" \
 "\n" \
-"/* Having the multiply constant hardcoded in the code makes things about\n" \
-" * 8%% faster; however, I want to make it a variable because then it\n" \
-" * can easily be changed in one's dwood2rc file, allowing people to \n" \
-" * protect themselves from \"make a bunch of bogus queries that hash to \n" \
-" * the same value\" DOS attacks.  However, if you need that extra 8%% \n" \
-" * speed, uncomment the next line, but change the constant to some other\n" \
-" * 32-bit prime number */\n" \
-"/*#define MUL_CONSTANT %d */ \n" \
-"uint32_t magic_number = %d;\n" \
+"#define MUL_CONSTANT %d \n" 
 
 /* Find a random 31-bit prime number */
 
--- deadwood-2.9.06/src/DwSys.h	2010-09-03 07:03:38.000000000 -0700
+++ deadwood-2.9.07/src/DwSys.h	2010-09-08 18:26:17.000000000 -0700
@@ -74,6 +74,9 @@
  * minimum log level that we log this at */
 void dw_log_number(char *s1, int number, char *s2, int min_log_level);
 
+/* Log a string and a number in hex */
+void dw_log_hex(char *s1, uint32_t number, int min_log_level);
+
 /* Log 3 strings; input: Strings to log; minimum log level that we log these
  * strings at; this always logs and is run before Dwood2rc file is parsed */
 void dw_alog_3strings(char *s1, char *s2, char *s3);
--- deadwood-2.9.06/src/DwSys.c	2010-09-03 07:03:38.000000000 -0700
+++ deadwood-2.9.07/src/DwSys.c	2010-09-08 18:26:17.000000000 -0700
@@ -292,6 +292,21 @@
 
 }
 
+void dw_log_hex(char *s1, uint32_t number, int min_log_level) {
+        int32_t ll = key_n[DWM_N_verbose_level];
+
+        if(ll <= 0 || ll < min_log_level) {
+                return;
+        }
+
+#ifndef MINGW
+        printf("%s%x\n",s1,number);
+#else /* MINGW */
+        dw_win_time();
+        fprintf(LOG,"%s%x\n",s1,number);
+#endif /* MINGW */
+}	
+
 /* Log 3 strings; input: Strings to log; minimum log level that we log these
  * strings at; this always logs and is run before Dwood2rc file is parsed */
 void dw_alog_3strings(char *s1, char *s2, char *s3) {
--- deadwood-2.9.06/src/DwMain.c	2010-09-03 07:03:38.000000000 -0700
+++ deadwood-2.9.07/src/DwMain.c	2010-09-08 18:26:01.000000000 -0700
@@ -76,6 +76,7 @@
 /* DNS non-recursive caching server */
 int dw_udp_main(int argc, char **argv) {
         int bind_count = 0; /* Number of IPs we bound to */
+	set_add_constant(); /* Has to be done before processing mararc */
         dw_parse_args(argc,argv);
         dw_show_programname();
         process_mararc_params();
--- deadwood-2.9.06/src/DwHash.h	2010-09-03 07:03:38.000000000 -0700
+++ deadwood-2.9.07/src/DwHash.h	2010-09-08 18:26:17.000000000 -0700
@@ -48,6 +48,10 @@
         int32_t max;  /* Maximum number of elements in hash */
 } dw_hash;
 
+/* Called before reading dwood3rc, this sets add_constant based on
+ * secret.txt in Windows and /dev/urandom in Unix */
+void set_add_constant();
+
 /* Zap (destroy) a created hash */
 void dwh_hash_zap(dw_hash *hash);
 
--- deadwood-2.9.06/sqa/do.tests	2010-08-06 09:41:58.000000000 -0700
+++ deadwood-2.9.07/sqa/do.tests	2010-09-08 18:26:17.000000000 -0700
@@ -152,7 +152,7 @@
 sleep 2
 if ! cmp output.success output.test > /dev/null 2>&1 ; then
 	echo test dwood2rc_n_hash_magic_number failed
-	exit 1
+	#exit 1
 else
 	echo test dwood2rc_n_hash_magic_number succeeded
 fi
--- deadwood-2.9.06/sqa/do.tests.CentOS-5.3	2010-08-06 09:41:58.000000000 -0700
+++ deadwood-2.9.07/sqa/do.tests.CentOS-5.3	2010-09-08 18:26:17.000000000 -0700
@@ -139,7 +139,7 @@
 sleep 2
 if ! cmp output.success output.test > /dev/null 2>&1 ; then
 	echo test dwood2rc_n_hash_magic_number failed
-	exit 1
+	#exit 1
 else
 	echo test dwood2rc_n_hash_magic_number succeeded
 fi
--- deadwood-2.9.07/doc/Deadwood.ej.orig	2010-09-08 12:19:40.000000000 -0700
+++ deadwood-2.9.07/doc/Deadwood.ej	2010-09-08 12:19:40.000000000 -0700
@@ -106,10 +106,12 @@
 the sender of the UDP query.  The default value for this is 1.
 
 <h2>hash_magic_number</h2>  
-This is a large 31-bit prime number that the hash compression function 
-uses; use the RandomPrime C program to generate a suitable random prime 
-for this function.  This number should be secret; its default value 
-changes for every release of Deadwood.
+This used to be used for Deadwood's internal hash generator to keep
+the hash generator somewhat random and immune to certain types of attacks.
+In Deadwood 3.0, entropy for the hash function is created by looking
+at the contents of /dev/urandom (secret.txt on Windows machines) and the
+current timestamp.  This parameter is only here so older configuration
+files do not break in Deadwood 3.0.
 
 <h2>ip_blacklist</h2>
 This is a list of IPs that we do not allow to be in the answer to a
@@ -207,6 +209,12 @@
 is used as a seed for the cryptographically strong random number generator.  
 Deadwood will try to read 256 bytes from this file (the RNG Deadwood uses can 
 accept a stream of any arbitrary length).
+<p>
+
+Note that the hash compression function obtains some of its entropy before 
+parsing the mararc file, and is hard-coded to get entropy from /dev/urandom
+(secret.txt on Windows systems).  Most other entropy used by Deadwood 
+comes from the file pointed to by random_seed_file.
 
 <h2>recurse_min_bind_port</h2>
 The lowest numbered port Deadwood is 
@@ -525,11 +533,12 @@
 
 <p>
 
-If using a precompiled binary of Deadwood, or if using a system where it is
-not feasible to add /dev/urandom support, one can use another system to
-generate a 31-bit random prime (perhaps using a different system with
-/dev/urandom support), then use the hash_magic_number parameter to have
-Deadwood use this random prime number.
+If using a precompiled binary of Deadwood, please ensure that the system
+has /dev/urandom support (on Windows system, please ensure that the
+file with the name secret.txt is generated by the included mkSecretTxt.exe
+program); Deadwood, at runtime, uses /dev/urandom (secret.txt in Windows)
+as a hardcoded path to get entropy (along with the timestamp) for the
+hash algorithm.
 
 <h1>DAEMONIZATION</h1>
 
