Exemple #1
0
/*
 * Find the resolution of the high-resolution clock by sampling successive
 * values until a tick boundary, at which point the delta is entered into
 * a table.  An average near the median of the table is taken and returned
 * as the system tick size to eliminate outliers due to descheduling (high)
 * or tv0 not being the "zero" time in a given tick (low).
 *
 * Some trickery is needed to defeat the habit systems have of always
 * incrementing the microseconds field from gettimeofday() results so that
 * no two calls return the same value.  Thus, a "tick boundary" is assumed
 * when successive calls return a difference of more than MINTICK ticks.
 * (For gettimeofday(), this is set to 2 us.)  This catches cases where at
 * most one other task reads the clock between successive reads by this task.
 * More tasks in between are rare enough that they'll get cut off by the
 * median filter.
 *
 * When a tick boundary is found, the *first* time read during the previous
 * tick (tv0) is subtracted from the new time to get microseconds per tick.
 *
 * Suns have a 1 us timer, and as of SunOS 4.1, they return that timer, but
 * there is ~50 us of system-call overhead to get it, so this overestimates
 * the tick size considerably.  On SunOS 5.x/Solaris, the overhead has been
 * cut to about 2.5 us, so the measured time alternates between 2 and 3 us.
 * Some better algorithms will be required for future machines that really
 * do achieve 1 us granularity.
 *
 * Current best idea: discard all this hair and use Ueli Maurer's entropy
 * estimation scheme.  Assign each input event (delta) a sequence number.
 * 16 bits should be more than adequate.  Make a table of the last time
 * (by sequence number) each possibe input event occurred.  For practical
 * implementation, hash the event to a fixed-size code and consider two
 * events identical if they have the same hash code.  This will only ever
 * underestimate entropy.  Then use the number of bits in the difference
 * between the current sequence number and the previous one as the entropy
 * estimate.
 *
 * If it's desirable to use longer contexts, Maurer's original technique
 * just groups events into non-overlapping pairs and uses the technique on
 * the pairs.  If you want to increment the entropy numbers on each keystroke
 * for user-interface niceness, you can do the operation each time, but you
 * have to halve the sequence number difference before starting, and then you
 * have to halve the number of bits of entropy computed because you're adding
 * them twice.
 *
 * You can put the even and odd events into separate tables to close Maurer's
 * model exactly, or you can just dump them into the same table, which will
 * be more conservative.
 */
static PGPUInt32
ranTickSize(void)
{
	int i = 0, j = 0;
	PGPUInt32	diff, d[kNumDeltas];
	timetype	tv0, tv1, tv2;
	
	/*
	 * TODO Get some per-run data to seed the RNG with.
	 * pid, ppid, etc.
	 */
	GetClock(&tv0);
	tv1 = tv0;
	do {
		GetClock(&tv2);
		diff = tickdiff(tv2, tv1);
		if (diff > MINTICK) {
			d[i++] = diff;
			tv0 = tv2;
			j = 0;
		} else if (++j >= 4096)	/* Always getting <= MINTICK units */
			return MINTICK + !MINTICK;
		tv1 = tv2;
	} while (i < kNumDeltas);

	/* Return average of middle 5 values (rounding up) */
	qsort(d, kNumDeltas, sizeof(d[0]), ranCompare);
	diff = (d[kNumDeltas / 2 - 2] + d[kNumDeltas / 2 - 1] +
			d[kNumDeltas / 2] + d[kNumDeltas / 2 + 1] +
			d[kNumDeltas/2 + 2] + 4) / 5;
#if NOISEDEBUG
	fprintf(stderr, "Tick size is %u\n", diff);
#endif
	return diff;
}
Exemple #2
0
/*
 * Find the resolution of the high-resolution clock by sampling successive
 * values until a tick boundary, at which point the delta is entered into
 * a table.  An average near the median of the table is taken and returned
 * as the system tick size to eliminate outliers due to descheduling (high)
 * or tv0 not being the "zero" time in a given tick (low).
 *
 * Some trickery is needed to defeat the habit systems have of always
 * incrementing the microseconds field from gettimeofday() results so that
 * no two calls return the same value.  Thus, a "tick boundary" is assumed
 * when successive calls return a difference of more than MINTICK ticks.
 * (For gettimeofday(), this is set to 2 us.)  This catches cases where at
 * most one other task reads the clock between successive reads by this task.
 * More tasks in between are rare enough that they'll get cut off by the
 * median filter.
 *
 * When a tick boundary is found, the *first* time read during the previous
 * tick (tv0) is subtracted from the new time to get microseconds per tick.
 *
 * Suns have a 1 us timer, and as of SunOS 4.1, they return that timer, but
 * there is ~50 us of system-call overhead to get it, so this overestimates
 * the tick size considerably.  On SunOS 5.x/Solaris, the overhead has been
 * cut to about 2.5 us, so the measured time alternates between 2 and 3 us.
 * Some better algorithms will be required for future machines that really
 * do achieve 1 us granularity.
 *
 * Current best idea: discard all this hair and use Ueli Maurer's entropy
 * estimation scheme.  Assign each input event (delta) a sequence number.
 * 16 bits should be more than adequate.  Make a table of the last time
 * (by sequence number) each possibe input event occurred.  For practical
 * implementation, hash the event to a fixed-size code and consider two
 * events identical if they have the same hash code.  This will only ever
 * underestimate entropy.  Then use the number of bits in the difference
 * between the current sequence number and the previous one as the entropy
 * estimate.
 *
 * If it's desirable to use longer contexts, Maurer's original technique
 * just groups events into non-overlapping pairs and uses the technique on
 * the pairs.  If you want to increment the entropy numbers on each keystroke
 * for user-interface niceness, you can do the operation each time, but you
 * have to halve the sequence number difference before starting, and then you
 * have to halve the number of bits of entropy computed because you're adding
 * them twice.
 *
 * You can put the even and odd events into separate tables to close Maurer's
 * model exactly, or you can just dump them into the same table, which will
 * be more conservative.
 */
static unsigned
noiseTickSize(void)
{
	unsigned i = 0, j = 0,  diff, d[N];
	timetype tv0, tv1, tv2;

	gettime(&tv0);
	tv1 = tv0;
	do {
		gettime(&tv2);
		diff = (unsigned)tickdiff(tv2, tv1);
		if (diff > MINTICK) {
			d[i++] = diff;
			tv0 = tv2;
			j = 0;
		} else if (++j >= 4096)	/* Always getting <= MINTICK units */
			return MINTICK + !MINTICK;
		tv1 = tv2;
	} while (i < N);

	/* Return average of middle 5 values (rounding up) */
	qsort(d, N, sizeof(d[0]), noiseCompare);
	diff = (d[N/2-2]+d[N/2-1]+d[N/2]+d[N/2+1]+d[N/2+2]+4)/5;
#if NOISEDEBUG
	fprintf(stderr, "Tick size is %u\n", diff);
#endif
	return diff;
}
Exemple #3
0
/*
 * Add as much timing-dependent random noise as possible
 * to the randPool.  Typically, this involves reading the most
 * accurate system clocks available.
 *
 * Returns the number of ticks that have passed since the last call,
 * for entropy estimation purposes.
 */
	PGPUInt32
pgpRandomCollectEntropy(PGPRandomContext const *rc)
{
	PGPUInt32 delta;
	timetype t;
	static PGPUInt32 ticksize = 0;
	static timetype prevt;

	GetClock(&t);
	pgpRandomAddBytes(rc, (PGPByte const *)&t, sizeof(t));

	if (!ticksize)
	{
		ticksize = ranTickSize();
		prevt = t;
	}
	delta = (PGPUInt32)(tickdiff(t, prevt) / ticksize);
	prevt = t;

	return delta;
}
Exemple #4
0
StackTrace::~StackTrace()
{
    m_iStackNum--;
    strcpy(m_szCurrent, m_pNodes[m_iStackNum].m_szFunction);

    if(m_pNodes[m_iStackNum].m_bLogging == true)
    {
        debug("%-*s%s exit (mem: %ld bytes, %ld ms)\n", m_iStackNum, "", m_pNodes[m_iStackNum].m_szFunction, memusage(), tickdiff(m_pNodes[m_iStackNum].m_dTick));
    }
}
Exemple #5
0
int main(int argc, char **argv)
{
   int iDebugLevel = 0, iNumMsgs = 0;
   long lMessageID = -1, lParentID = -1, lFolderID = -1, lDate = 0, lFromID = -1, lToID = -1;
   char *szSQL = NULL;
   bytes *pText = NULL, *pSubject = NULL, *pEDF = NULL;
   EDF *pSearch = NULL;
   DBTable *pTable = NULL;
   double dTick = 0;

   if(argc != 3 || !(strcmp(argv[1], "-edf") == 0 || strcmp(argv[1], "-query") == 0))
   {
      printf("Usage: Searching -edf <file>\n");
      printf("Usage: Searching -query <string>\n");

      return 1;
   }

   if(strcmp(argv[1], "-edf") == 0)
   {
      pSearch = EDFParser::FromFile(argv[2]);
      if(pSearch == NULL)
      {
         printf("Could not parse %s, %s\n", argv[2], strerror(errno));
         return 1;
      }

      EDFParser::Print("Search", pSearch);
   }
   else
   {
      pSearch = QueryToEDF(argv[2]);

      printf("Query %s\n", argv[2]);
      EDFParser::Print("Search", pSearch);

      // return 0;
   }
   printf("\n");

   dTick = gettick();
   szSQL = MessageSQL(pSearch);
   printf("SQL(%ld ms): %s\n", tickdiff(dTick), szSQL);
   if(szSQL == NULL)
   {
      printf("Nothing to search for\n");

      return 1;
   }

   if(DBTable::Connect("ua27") == false)
   {
      printf("Cannot connect to database, %s\n", strerror(errno));

      delete pSearch;

      return 1;
   }

   pTable = new DBTable();

   printf("Binding columns\n");

   // messageid
   pTable->BindColumnInt();

   // parentid
   pTable->BindColumnInt();

   // treeid, date, fromid, toid, text
   pTable->BindColumnInt();
   pTable->BindColumnInt();
   pTable->BindColumnInt();
   pTable->BindColumnInt();
   pTable->BindColumnBytes();

   // subject
   pTable->BindColumnBytes();

   // edf
   pTable->BindColumnBytes();

   dTick = gettick();
   printf("Running query\n");
   if(pTable->Execute(szSQL) == true)
   {
      printf("Execute(%ld ms)\n", tickdiff(dTick));

      // iDebugLevel = debuglevel(DEBUGLEVEL_DEBUG);

      dTick = gettick();

      while(pTable->NextRow() == true)
      {
         iNumMsgs++;

         lMessageID = -1;

         lParentID = -1;

         lFolderID = -1;
         lDate = 0;
         lFromID = -1;
         lToID = -1;
         pText = NULL;

         pSubject = NULL;

         pEDF = NULL;

         // messageid
         pTable->GetField(0, &lMessageID);

         // parentid
         pTable->GetField(1, &lParentID);

         // treeid, date, fromid, toid, text
         pTable->GetField(2, &lFolderID);
         pTable->GetField(3, &lDate);
         pTable->GetField(4, &lFromID);
         pTable->GetField(5, &lToID);
         pTable->GetField(6, &pText);

         // subject
         pTable->GetField(7, &pSubject);

         // edf
         pTable->GetField(7, &pEDF);

         printf("m=%ld p=%ld f=%ld d=%ld %ld %ld", lMessageID, lParentID, lFolderID, lDate, lFromID, lToID);
         if(pSubject != NULL)
         {
            printf(", %s", (char *)pSubject->Data(false));
         }
         if(pText != NULL)
         {
            printf(":\n%s", (char *)pText->Data(false));
         }
         printf("\n");

         // delete pEDF;
         // delete pSubject;
         // delete pText;
      }

      // debuglevel(iDebugLevel);

      printf("Found %d messages(%ld ms)\n", iNumMsgs, tickdiff(dTick));
   }
   else
   {
      printf("Query failed, %s\n", strerror(errno));
   }

   delete pTable;

   DBTable::Disconnect();

   delete[] szSQL;

   delete pSearch;

   return 0;
}
Exemple #6
0
/*
 * Add as much environmentally-derived random noise as possible
 * to the randPool.  Typically, this involves reading the most
 * accurate system clocks available.
 *
 * Returns the number of ticks that have passed since the last call,
 * for entropy estimation purposes.
 */
word32
noise(void)
{
	word32 delta;

#if defined(MSDOS)
	static unsigned deltamask = 0;
	static unsigned prevt;
	unsigned t;
	time_t tnow;
	clock_t cnow;

	if (deltamask == 0)
		deltamask = has8254() ? 0xffff : 0x7fff;
	t = (deltamask & 0x8000) ? read8254() : read8253();
	randPoolAddBytes((byte const *)&t, sizeof(t));
	delta = deltamask & (t - prevt);
	prevt = t;

	/* Add more-significant time components. */
	cnow = clock();
	randPoolAddBytes((byte *)&cnow, sizeof(cnow));
	tnow = time((time_t *)0);
	randPoolAddBytes((byte *)&tnow, sizeof(tnow));
/* END OF DOS */
#elif defined(VMS)
	word32 t[2];	/* little-endian 64-bit timer */
	word32 d1;	/* MSW of difference */
	static word32 prevt[2];

	SYS$GETTIM(t);	/* VMS hardware clock increments by 100000 per tick */
	randPoolAddBytes((byte const *)t, sizeof(t));
	/* Get difference in d1 and delta, and old time in prevt */
	d1 = t[1] - prevt[1] + (t[0] < prevt[0]);
	prevt[1] = t[1];
	delta = t[0] - prevt[0];
	prevt[0] = t[0];
	
	/* Now, divide the 64-bit value by 100000 = 2^5 * 5^5 = 32 * 3125 */
	/* Divide value, MSW in d1 and LSW in delta, by 32 */
	delta >>= 5;
	delta |= d1 << (32-5);
	d1 >>= 5;
	/*
	 * Divide by 3125.  This fits into 16 bits, so the following
	 * code is possible.  2^32 = 3125 * 1374389 + 1671.
	 *
	 * This code has confused people reading it, so here's a detailed
	 * explanation.  First, since we only want a 32-bit result,
	 * reduce the input mod 3125 * 2^32 before starting.  This
	 * amounts to reducing the most significant word mod 3125 and
	 * leaving the least-significant word alone.
	 *
	 * Then, using / for mathematical (real, not integer) division, we
	 * want to compute floor(d1 * 2^32 + d0) / 3125), which I'll denote
	 * using the old [ ] syntax for floor, so it's
	 *   [ (d1 * 2^32 + d0) / 3125 ]
	 * = [ (d1 * (3125 * 1374389 + 1671) + d0) / 3125 ]
	 * = [ d1 * 1374389 + (d1 * 1671 + d0) / 3125 ]
	 * = d1 * 137438 + [ (d1 * 1671 + d0) / 3125 ]
	 * = d1 * 137438 + [ d0 / 3125 ] + [ (d1 * 1671 + d0 % 3125) / 3125 ]
	 *
	 * The C / operator, applied to integers, performs [ a / b ], so
	 * this can be implemented in C, and since d1 < 3125 (by the first
	 * modulo operation), d1 * 1671 + d0 % 3125 < 3125 * 1672, which
	 * is 5225000, less than 2^32, so it all fits into 32 bits.
	 */
	d1 %= 3125;	/* Ignore overflow past 32 bits */
	delta = delta/3125 + d1*1374389 + (delta%3125 + d1*1671) / 3125;
/* END OF VMS */
#elif defined(UNIX)
	timetype t;
	static unsigned ticksize = 0;
	static timetype prevt;

	gettime(&t);
#if CHOICE_GETITIMER
	/* If itimer isn't started, start it */
	if (t.it_value.tv_sec == 0 && t.it_value.tv_usec == 0) {
		/*
		 * start the timer - assume that PGP won't be running for
		 * more than 11 days, 13 hours, 46 minutes and 40 seconds.
		 */
		t.it_value.tv_sec = 1000000;
		t.it_interval.tv_sec = 1000000;
		t.it_interval.tv_usec = 0;
		signal(SIGALRM, SIG_IGN);	/* just in case.. */
		setitimer(ITIMER_REAL, &t, NULL);
		t.it_value.tv_sec = 0;
	}
	randPoolAddBytes((byte const *)&t.it_value, sizeof(t.it_value));
#else
	randPoolAddBytes((byte const *)&t, sizeof(t));
#endif

	if (!ticksize)
		ticksize = noiseTickSize();
	delta = (word32)(tickdiff(t, prevt) / ticksize);
	prevt = t;
/* END OF UNIX */
#else
#error Unknown OS - define UNIX or MSDOS or add code for high-resolution timers
#endif

	return delta;
}