You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by dg...@hyperreal.org on 1998/06/08 07:32:24 UTC
cvs commit: apache-1.3/src/modules/standard mod_unique_id.c
dgaudet 98/06/07 22:32:24
Modified: src CHANGES
src/modules/standard mod_unique_id.c
Log:
fix mod_unique_id to work with 64-bit time_t
Submitted by: Alvaro Martinez Echevarria <al...@lander.es>
Revision Changes Path
1.894 +4 -0 apache-1.3/src/CHANGES
Index: CHANGES
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v
retrieving revision 1.893
retrieving revision 1.894
diff -u -r1.893 -r1.894
--- CHANGES 1998/06/07 13:16:40 1.893
+++ CHANGES 1998/06/08 05:32:22 1.894
@@ -1,5 +1,9 @@
Changes with Apache 1.3.1
+ *) mod_unique_id did not work on alpha linux (in general on any
+ architecture that has 64-bit time_t).
+ [Alvaro Martinez Echevarria <al...@lander.es>]
+
*) PORT: Make SCO 5 (and probably 3) compile again. [Ben Laurie]
*) PORT: NCR MPRAS systems have the same bug with SIGHUP restart that
1.16 +88 -45 apache-1.3/src/modules/standard/mod_unique_id.c
Index: mod_unique_id.c
===================================================================
RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_unique_id.c,v
retrieving revision 1.15
retrieving revision 1.16
diff -u -r1.15 -r1.16
--- mod_unique_id.c 1998/04/11 12:00:53 1.15
+++ mod_unique_id.c 1998/06/08 05:32:24 1.16
@@ -59,6 +59,7 @@
* mod_unique_id.c: generate a unique identifier for each request
*
* Original author: Dean Gaudet <dg...@arctic.org>
+ * UUencoding modified by: Alvaro Martinez Echevarria <al...@lander.es>
*/
#include "httpd.h"
@@ -71,11 +72,11 @@
#endif
typedef struct {
- time_t stamp;
+ unsigned int stamp;
unsigned int in_addr;
unsigned int pid;
unsigned short counter;
-} unique_id_rec;
+} unique_id_rec;
/* Comments:
*
@@ -125,11 +126,35 @@
* procedure will ensure that the new space of identifiers is completely unique
* from the old space. (Since the first four unencoded bytes always differ.)
*/
+/*
+ * Sun Jun 7 05:43:49 CEST 1998 -- Alvaro
+ * More comments:
+ * 1) The UUencoding prodecure is now done in a general way, avoiding the problems
+ * with sizes and paddings that can arise depending on the architecture. Now the
+ * offsets and sizes of the elements of the unique_id_rec structure are calculated
+ * in unique_id_global_init; and then used to duplicate the structure without the
+ * paddings that might exist. The multithreaded server fix should be now very easy:
+ * just add a new "tid" field to the unique_id_rec structure, and increase by one
+ * UNIQUE_ID_REC_MAX.
+ * 2) unique_id_rec.stamp has been changed from "time_t" to "unsigned int", because
+ * its size is 64bits on some platforms (linux/alpha), and this caused problems with
+ * htonl/ntohl. Well, this shouldn't be a problem till year 2106.
+ */
static unsigned global_in_addr;
static APACHE_TLS unique_id_rec cur_unique_id;
+/*
+ * Number of elements in the structure unique_id_rec.
+ */
+#define UNIQUE_ID_REC_MAX 4
+
+static unsigned short unique_id_rec_offset[UNIQUE_ID_REC_MAX],
+ unique_id_rec_size[UNIQUE_ID_REC_MAX],
+ unique_id_rec_total_size,
+ unique_id_rec_size_uu;
+
static void unique_id_global_init(server_rec *s, pool *p)
{
#ifndef MAXHOSTNAMELEN
@@ -142,18 +167,23 @@
#endif
/*
- * First of all, verify some assumptions that have been made about the
- * contents of unique_id_rec. We do it this way because it isn't
- * affected by trailing padding.
+ * Calculate the sizes and offsets in cur_unique_id.
*/
- if (XtOffsetOf(unique_id_rec, counter) + sizeof(cur_unique_id.counter)
- != 14) {
- ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ALERT, s,
- "mod_unique_id: sorry the size assumptions are wrong "
- "in mod_unique_id.c, please remove it from your server "
- "or fix the code!");
- exit(1);
- }
+ unique_id_rec_offset[0] = XtOffsetOf(unique_id_rec, stamp);
+ unique_id_rec_size[0] = sizeof(cur_unique_id.stamp);
+ unique_id_rec_offset[1] = XtOffsetOf(unique_id_rec, in_addr);
+ unique_id_rec_size[1] = sizeof(cur_unique_id.in_addr);
+ unique_id_rec_offset[2] = XtOffsetOf(unique_id_rec, pid);
+ unique_id_rec_size[2] = sizeof(cur_unique_id.pid);
+ unique_id_rec_offset[3] = XtOffsetOf(unique_id_rec, counter);
+ unique_id_rec_size[3] = sizeof(cur_unique_id.counter);
+ unique_id_rec_total_size = unique_id_rec_size[0] + unique_id_rec_size[1] +
+ unique_id_rec_size[2] + unique_id_rec_size[3];
+
+ /*
+ * Calculate the size of the structure when uuencoded.
+ */
+ unique_id_rec_size_uu = (unique_id_rec_total_size*8+5)/6;
/*
* Now get the global in_addr. Note that it is not sufficient to use one
@@ -262,7 +292,7 @@
* identifiers are comparable between machines of different byte
* orderings. Note in_addr is already in network order.
*/
- cur_unique_id.pid = htons(cur_unique_id.pid);
+ cur_unique_id.pid = htonl(cur_unique_id.pid);
cur_unique_id.counter = htons(cur_unique_id.counter);
}
@@ -281,11 +311,19 @@
static int gen_unique_id(request_rec *r)
{
- /* when we uuencode it will take 19 bytes plus \0 */
- char str[19 + 1];
- const unsigned char *x;
+ char *str;
+ /*
+ * Buffer padded with two final bytes, used to copy the unique_id_red
+ * structure without the internal paddings that it could have.
+ */
+ struct {
+ unique_id_rec foo;
+ unsigned char pad[2];
+ } paddedbuf;
+ unsigned char *x,*y;
unsigned short counter;
char *e;
+ int i,j,k;
/* copy the unique_id if this is an internal redirect (we're never
* actually called for sub requests, so we don't need to test for
@@ -295,36 +333,41 @@
return DECLINED;
}
- cur_unique_id.stamp = htonl(r->request_time);
+ cur_unique_id.stamp = htonl((unsigned int)r->request_time);
- /* do the uuencoding */
- x = (const unsigned char *) &cur_unique_id;
- str[0] = uuencoder[x[0] >> 2];
- str[1] = uuencoder[((x[0] & 0x03) << 4) | ((x[1] & 0xf0) >> 4)];
- str[2] = uuencoder[((x[1] & 0x0f) << 2) | ((x[2] & 0xc0) >> 6)];
- str[3] = uuencoder[x[2] & 0x3f];
- x += 3;
- str[4] = uuencoder[x[0] >> 2];
- str[5] = uuencoder[((x[0] & 0x03) << 4) | ((x[1] & 0xf0) >> 4)];
- str[6] = uuencoder[((x[1] & 0x0f) << 2) | ((x[2] & 0xc0) >> 6)];
- str[7] = uuencoder[x[2] & 0x3f];
- x += 3;
- str[8] = uuencoder[x[0] >> 2];
- str[9] = uuencoder[((x[0] & 0x03) << 4) | ((x[1] & 0xf0) >> 4)];
- str[10] = uuencoder[((x[1] & 0x0f) << 2) | ((x[2] & 0xc0) >> 6)];
- str[11] = uuencoder[x[2] & 0x3f];
- x += 3;
- str[12] = uuencoder[x[0] >> 2];
- str[13] = uuencoder[((x[0] & 0x03) << 4) | ((x[1] & 0xf0) >> 4)];
- str[14] = uuencoder[((x[1] & 0x0f) << 2) | ((x[2] & 0xc0) >> 6)];
- str[15] = uuencoder[x[2] & 0x3f];
- x += 3;
- str[16] = uuencoder[x[0] >> 2];
- str[17] = uuencoder[((x[0] & 0x03) << 4) | ((x[1] & 0xf0) >> 4)];
- str[18] = uuencoder[((x[1] & 0x0f) << 2) | ((0 & 0xc0) >> 6)];
- str[19] = '\0';
+ /* we'll use a temporal buffer to avoid uuencoding the possible internal
+ * paddings of the original structure */
+ x = (unsigned char *) &paddedbuf;
+ y = (unsigned char *) &cur_unique_id;
+ k = 0;
+ for (i = 0; i < UNIQUE_ID_REC_MAX; i++) {
+ y = ((unsigned char *) &cur_unique_id) + unique_id_rec_offset[i];
+ for (j = 0; j < unique_id_rec_size[i]; j++, k++) {
+ x[k] = y[j];
+ }
+ }
+ /*
+ * We reset two more bytes just in case padding is needed for the uuencoding.
+ */
+ x[k++] = '\0';
+ x[k++] = '\0';
+
+ /* alloc str and do the uuencoding */
+ str = (char *)ap_palloc(r->pool, unique_id_rec_size_uu + 1);
+ k = 0;
+ for (i = 0; i < unique_id_rec_total_size; i += 3) {
+ y = x + i;
+ str[k++] = uuencoder[y[0] >> 2];
+ str[k++] = uuencoder[((y[0] & 0x03) << 4) | ((y[1] & 0xf0) >> 4)];
+ if (k == unique_id_rec_size_uu) break;
+ str[k++] = uuencoder[((y[1] & 0x0f) << 2) | ((y[2] & 0xc0) >> 6)];
+ if (k == unique_id_rec_size_uu) break;
+ str[k++] = uuencoder[y[2] & 0x3f];
+ }
+ str[k++] = '\0';
- ap_table_setn(r->subprocess_env, "UNIQUE_ID", ap_pstrdup(r->pool, str));
+ /* set the environment variable */
+ ap_table_setn(r->subprocess_env, "UNIQUE_ID", str);
/* and increment the identifier for the next call */
counter = ntohs(cur_unique_id.counter) + 1;