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;