void ssl_scache_shmht_init(server_rec *s, pool *p)
{
    SSLModConfigRec *mc = myModConfig();
    AP_MM *mm;
    table_t *ta;
    int ta_errno;
    int avail;
    int n;

    /*
     * Create shared memory segment
     */
    if (mc->szSessionCacheDataFile == NULL) {
        ssl_log(s, SSL_LOG_ERROR, "SSLSessionCache required");
        ssl_die();
    }
    if ((mm = ap_mm_create(mc->nSessionCacheDataSize, 
                           mc->szSessionCacheDataFile)) == NULL) {
        ssl_log(s, SSL_LOG_ERROR, 
                "Cannot allocate shared memory: %s", ap_mm_error());
        ssl_die();
    }
    mc->pSessionCacheDataMM = mm;

    /* 
     * Make sure the childs have access to the underlaying files
     */
    ap_mm_permission(mm, SSL_MM_FILE_MODE, ap_user_id, -1);

    /*
     * Create hash table in shared memory segment
     */
    avail = ap_mm_available(mm);
    n = (avail/2) / 1024;
    n = n < 10 ? 10 : n;
    if ((ta = table_alloc(n, &ta_errno, 
                          ssl_scache_shmht_malloc,  
                          ssl_scache_shmht_calloc, 
                          ssl_scache_shmht_realloc, 
                          ssl_scache_shmht_free    )) == NULL) {
        ssl_log(s, SSL_LOG_ERROR,
                "Cannot allocate hash table in shared memory: %s",
                table_strerror(ta_errno));
        ssl_die();
    }
    table_attr(ta, TABLE_FLAG_AUTO_ADJUST|TABLE_FLAG_ADJUST_DOWN);
    table_set_data_alignment(ta, sizeof(char *));
    table_clear(ta);
    mc->tSessionCacheDataTable = ta;

    /*
     * Log the done work
     */
    ssl_log(s, SSL_LOG_INFO, 
            "Init: Created hash-table (%d buckets) "
            "in shared memory (%d bytes) for SSL session cache", n, avail);
    return;
}
Exemple #2
0
/*
 * perform some basic tests
 */
static	void	basic(table_t *tab_p)
{
  long	key;
  int	ret;
  void	*data_p;
  
  (void)printf("Performing basic tests:\n");
  (void)fflush(stdout);
  
  key = TEST_VALUE;
  ret = table_insert(tab_p, &key, sizeof(key), NULL, 0, &data_p, 0);
  if (ret != TABLE_ERROR_NONE) {
    (void)fprintf(stderr,
		  "could not store null pointer of size 0 in table: %s\n",
		 table_strerror(ret));
    exit(1);
  }
  
  /* try the replace */
  ret = table_insert(tab_p, &key, sizeof(key), NULL, 0, &data_p, 1);
  if (ret != TABLE_ERROR_NONE) {
    (void)fprintf(stderr,
		  "could not store null pointer of size 0 in table: %s\n",
		 table_strerror(ret));
    exit(1);
  }
  
  /* try to insert without replace */
  ret = table_insert(tab_p, &key, sizeof(key), NULL, 0, &data_p, 0);
  if (ret != TABLE_ERROR_OVERWRITE) {
    (void)printf("replaced a key in the table with no-overwrite flag: %s\n",
		 table_strerror(ret));
    exit(1);
  }
  
  /* delete the key */
  ret = table_delete(tab_p, &key, sizeof(key), NULL, NULL);
  if (ret != TABLE_ERROR_NONE) {
    (void)fprintf(stderr, "could not delete test key %ld: %s\n",
		  key, table_strerror(ret));
    exit(1);
  }
  
  /* test to make sure we can insert a NULL with size > 0 */
  ret = table_insert(tab_p, &key, sizeof(key), NULL, 100, &data_p, 0);
  if (ret != TABLE_ERROR_NONE) {
    (void)printf("could not add NULL with size > 0: %s\n",
		 table_strerror(ret));
    exit(1);
  }
  ret = table_delete(tab_p, &key, sizeof(key), NULL, NULL);
  if (ret != TABLE_ERROR_NONE) {
    (void)fprintf(stderr, "could not delete test key %ld: %s\n",
		  key, table_strerror(ret));
    exit(1);
  }
}
Exemple #3
0
/*
 * dump the table to stdout
 */
static	void	dump_table(table_t *tab_p)
{
  int	ret, entry_c;
  long	*data_p, *key_p;
  
  for (ret = table_first(tab_p, (void **)&key_p, NULL, (void **)&data_p, NULL),
	 entry_c = 0;
       ret == TABLE_ERROR_NONE;
       ret = table_next(tab_p, (void **)&key_p, NULL, (void **)&data_p, NULL),
	 entry_c++) {
    (void)printf("%d: key %ld, data %ld\n", entry_c, *key_p, *data_p);
  }
  
  if (ret != TABLE_ERROR_NOT_FOUND) {
    (void)fprintf(stderr, "ERROR: first or next key in table: %s\n",
		  table_strerror(ret));
  }
}
Exemple #4
0
/*
 * compare the keys in two tables.  returns 1 if equal else 0
 */
static	int	test_eq(table_t *tab1_p, table_t *tab2_p, const int verb_b)
{
  int	ret, eq = 1, key_size, data1_size, data2_size;
  void	*key_p, *data1_p, *data2_p;
  
  /* test the table entries */
  for (ret = table_first(tab1_p, (void **)&key_p, &key_size,
			 (void **)&data1_p, &data1_size);
       ret == TABLE_ERROR_NONE;
       ret = table_next(tab1_p, (void **)&key_p, &key_size,
			(void **)&data1_p, &data1_size)) {
    ret = table_retrieve(tab2_p, key_p, key_size,
			 (void **)&data2_p, &data2_size);
    if (ret != TABLE_ERROR_NONE) {
      (void)fprintf(stderr, "could not find key of %d bytes: %s\n",
		    key_size, table_strerror(ret));
      eq = 0;
    }
    else if (data1_size == data2_size
	     && memcmp(data1_p, data2_p, data1_size) == 0) {
      if (verb_b) {
	(void)printf("key of %d bytes, data of %d bytes\n",
		     key_size, data1_size);
	fflush(stdout);
      }
    }
    else {
      (void)fprintf(stderr,
		    "ERROR: key of %d bytes: data (size %d) != other "
		    "(size %d)\n",
		    key_size, data1_size, data2_size);
      eq = 0;
    }
  }
  
  if (ret != TABLE_ERROR_NOT_FOUND) {
    eq = 0;
  }
  return eq;
}
Exemple #5
0
/*
 * perform some basic tests
 */
static	void	order_test(table_t *tab_p)
{
  table_entry_t		**entries, **entries_p;
  table_linear_t	*linears, *linears_p;
  void			*key_p, *last_key;
  void			*key, *data, *key2, *data2;
  int			error, entry_n, last_ksize, size, cmp;
  int			ret, ksize, dsize, ksize2, dsize2;
  
  (void)printf("Performing ordering tests:\n");
  (void)fflush(stdout);
  
  /* order the table */
  entries = table_order(tab_p, NULL, &entry_n, &error);
  if (entries == NULL) {
    (void)fprintf(stderr, "could not order table: %s\n",
		  table_strerror(error));
    exit(1);
  }
  
  /* order the table with the pos method */
  linears = table_order_pos(tab_p, NULL, &entry_n, &error);
  if (linears == NULL) {
    (void)fprintf(stderr, "could not order-pos table: %s\n",
		  table_strerror(error));
    exit(1);
  }
  
  last_key = NULL;
  last_ksize = 0;
  
  for (entries_p = entries, linears_p = linears;
       entries_p < entries + entry_n;
       entries_p++, linears_p++) {
    
    /* get the entry */
    error = table_entry(tab_p, *entries_p, &key, &ksize, &data, &dsize);
    if (error != TABLE_ERROR_NONE) {
      (void)fprintf(stderr, "could not get-entry from table: %s\n",
		    table_strerror(error));
      exit(1);
    }
    
    if (verbose_b) {
      for (key_p = key;
	   (char *)key_p < (char *)key + ksize
	     && (char *)key_p < (char *)key + MAX_ORDER_DUMP;
	   key_p = (char *)key_p + 1) {
	(void)printf("%03d ", *(unsigned char *)key_p);
      }
      if (ksize > MAX_ORDER_DUMP) {
	(void)fputs("... ", stdout);
      }
      (void)printf("(%d)\n", ksize);
    }
    
    /* get the pos entry */
    error = table_entry_pos(tab_p, linears_p, &key2, &ksize2, &data2, &dsize2);
    if (error != TABLE_ERROR_NONE) {
      (void)fprintf(stderr, "could not get-entry-pos from table: %s\n",
		    table_strerror(error));
      exit(1);
    }
    
    /* make sure we get the same data */
    if (ksize != ksize2
	|| memcmp(key, key2, ksize) != 0
	|| dsize != dsize2
	|| memcmp(data, data2, dsize) != 0) {
      (void)fprintf(stderr,
		    "ERROR: entry and entry-pos output does not match\n");
      exit(1);
    }
    
    if (entries_p == entries) {
      continue;
    }
    
    /* compare with the last key */
    size = last_ksize;
    if (ksize < size) {
      size = ksize;
    }
    cmp = memcmp(last_key, key, size);
    if (cmp > 0	|| (cmp == 0 && last_ksize > ksize)) {
      (void)fprintf(stderr, "ERROR: entries not in order!!\n");
      exit(1);
    }
  }
  
  if (entries_p > entries + 1) {
    size = last_ksize;
    if (ksize < size) {
      size = ksize;
    }
    cmp = memcmp(last_key, key, size);
    if (cmp > 0	|| (cmp == 0 && last_ksize > ksize)) {
      (void)fprintf(stderr, "ERROR: entries not in order!!\n");
      exit(1);
    }
  }
  
  /* free the ordered arrays */
  ret = table_order_free(tab_p, entries, entry_n);
  if (ret != TABLE_ERROR_NONE) {
    (void)fprintf(stderr, "could not free table order array: %s\n",
		  table_strerror(ret));
  }
  ret = table_order_pos_free(tab_p, linears, entry_n);
  if (ret != TABLE_ERROR_NONE) {
    (void)fprintf(stderr, "could not free table order pos array: %s\n",
		  table_strerror(ret));
  }
}
Exemple #6
0
/*
 * perform some basic tests
 */
static	void	io_test(table_t *tab_p)
{
  int		ret, bucket_n, entry_n;
  table_t	*tab2_p;
  
  (void)printf("Performing I/O tests:\n");
  (void)fflush(stdout);
  
#if 0
  {
    long	key, data;
    (void)table_clear(tab_p);
    key = 1;
    data = 2;
    (void)table_insert(tab_p, &key, sizeof(key), &data, sizeof(data), NULL, 0);
    key = 3;
    data = 4;
    (void)table_insert(tab_p, &key, sizeof(key), &data, sizeof(data), NULL, 0);
    key = 5;
    data = 6;
    (void)table_insert(tab_p, &key, sizeof(key), &data, sizeof(data), NULL, 0);
    (void)table_adjust(tab_p, 0);
    dump_table(tab_p);
  }
#endif
  
  ret = table_info(tab_p, &bucket_n, &entry_n);
  if (ret != TABLE_ERROR_NONE) {
    (void)fprintf(stderr, "could not get info of table: %s\n",
		  table_strerror(ret));
    exit(1);
  }
  (void)printf("Table we are writing has %d buckets and %d entries\n",
	       bucket_n, entry_n);
  
  /*
   * dump the table to disk
   */
  int pmode = 0640;
#ifdef win32
  pmode = _S_IREAD | _S_IWRITE;
#endif
  (void)unlink(TABLE_FILE);
  ret = table_write(tab_p, TABLE_FILE, pmode);
  if (ret != TABLE_ERROR_NONE) {
    (void)fprintf(stderr, "could not write table to '%s': %s\n",
		  TABLE_FILE, table_strerror(ret));
    exit(1);
  }
  
#if 0
  dump_table(tab_p);
#endif
  
  /*
   * now read back in the table
   */
  tab2_p = table_read(TABLE_FILE, &ret);
  if (tab2_p == NULL) {
    (void)fprintf(stderr, "could not read in file '%s': %s\n",
		  TABLE_FILE, table_strerror(ret));
    exit(1);
  }
  
  (void)printf("Testing table-read...\n");
  if (test_eq(tab_p, tab2_p, 0)) {
    (void)printf("  equal.\n");
  }
  else {
    (void)printf("  NOT equal.\n");
  }
  
  ret = table_free(tab2_p);
  if (ret != TABLE_ERROR_NONE) {
    (void)fprintf(stderr, "could not free read table: %s\n",
		  table_strerror(ret));
    exit(1);
  }
  
  /*
   * mmap in the table
   */
  tab2_p = table_mmap(TABLE_FILE, &ret);
  if (tab2_p == NULL) {
    (void)fprintf(stderr, "could not mmap file '%s': %s\n",
		  TABLE_FILE, table_strerror(ret));
    exit(1);
  }
  
  (void)printf("Testing table-mmap...\n");
  if (test_eq(tab2_p, tab_p, 0)) {
    (void)printf("  equal.\n");
  }
  else {
    (void)printf("  NOT equal.\n");
  }
  
  ret = table_munmap(tab2_p);
  if (ret != TABLE_ERROR_NONE) {
    (void)fprintf(stderr, "could not munmap file '%s': %s\n",
		  TABLE_FILE, table_strerror(ret));
    exit(1);
  }
}
Exemple #7
0
/*
 * try ITERN random program iterations.
 */
static	void	stress(table_t *tab_p, const int iter_n, const int mmaping_b)
{
  void		*data, *key;
  int		which = 0, mode, weight_total;
  int		iter_c, pnt_c, free_c, ret, ksize, dsize;
  entry_t	*grid, *free_p, *grid_p, *last_p;
  int		linear_b = 0, linear_eof_b = 0;
  
  (void)printf("Performing stress tests with %d iterations:\n", iter_n);
  (void)fflush(stdout);
  
  grid = malloc(sizeof(entry_t) * MAX_ENTRIES);
  if (grid == NULL) {
    (void)printf("problems allocating space for %d entries.\n",
		 MAX_ENTRIES);
    exit(1);
  }
  
  /* initialize free list */
  free_p = grid;
  for (grid_p = grid; grid_p < grid + MAX_ENTRIES; grid_p++) {
    grid_p->en_free_b = 1;
    grid_p->en_key = NULL;
    grid_p->en_key_size = 0;
    grid_p->en_data = NULL;
    grid_p->en_data_size = 0;
    grid_p->en_next_p = grid_p + 1;
  }
  /* redo the last next pointer */
  (grid_p - 1)->en_next_p = NULL;
  free_c = MAX_ENTRIES;
  
#if 0
  /* load the list */
  if (mmaping_b) {
    for (ret = table_first(tab_p, (void **)&key_p, NULL, (void **)&data_p,
			   NULL);
	 ret == TABLE_ERROR_NONE;
	 ret = table_next(tab_p, (void **)&key_p, NULL, (void **)&data_p,
			  NULL)) {
    }
  }
#endif
  
  /* total the weights */
  weight_total = 0;
  for (mode = 0; mode < MODE_MAX; mode++) {
    weight_total += mode_weights[mode];
  }
  
  for (iter_c = 0; iter_c < iter_n;) {
    int		weight;
    
    /* decide what to do */
    weight = RANDOM_VALUE(weight_total) + 1;
    for (mode = 0; mode < MODE_MAX; mode++) {
      weight -= mode_weights[mode];
      if (weight <= 0) {
	break;
      }
    }
    
    /* out of bounds */
    if (mode >= MODE_MAX) {
      continue;
    }
    
    switch (mode) {
      
    case MODE_CLEAR:
      if (mmaping_b || large_b) {
	continue;
      }
      
      call_c++;
      table_clear(tab_p);
      
      /* re-init free list */
      free_p = grid;
      for (grid_p = grid; grid_p < grid + MAX_ENTRIES; grid_p++) {
	if (! grid_p->en_free_b) {
	  if (grid_p->en_key != NULL) {
	    free(grid_p->en_key);
	  }
	  if (grid_p->en_data != NULL) {
	    free(grid_p->en_data);
	  }
	}
	grid_p->en_free_b = 1;
	grid_p->en_next_p = grid_p + 1;
      }
      /* redo the last next pointer */
      (grid_p - 1)->en_next_p = NULL;
      free_c = MAX_ENTRIES;
      linear_b = 0;
      linear_eof_b = 0;
      iter_c++;
      if (verbose_b) {
	(void)printf("table cleared.\n");
	fflush(stdout);
      }
      break;
      
    case MODE_INSERT:
      if (mmaping_b) {
	continue;
      }
      if (free_c > 0) {
	which = RANDOM_VALUE(free_c);
	last_p = NULL;
	grid_p = free_p;
	for (pnt_c = 0; pnt_c < which && grid_p != NULL; pnt_c++) {
	  last_p = grid_p;
	  grid_p = grid_p->en_next_p;
	}
	if (grid_p == NULL) {
	  (void)printf("reached end of free list prematurely\n");
	  exit(1);
	}
	
	do {
	  key = random_block(&ksize);
	} while (key == NULL);
	data = random_block(&dsize);
	
	call_c++;
	ret = table_insert(tab_p, key, ksize, data, dsize, NULL, 0);
	if (ret == TABLE_ERROR_NONE) {
	  if (verbose_b) {
	    (void)printf("stored in pos %d: %d, %d bytes of key, data\n",
			 grid_p - grid, ksize, dsize);
	    fflush(stdout);
	  }
	  
	  grid_p->en_free_b = 0;
	  grid_p->en_key = key;
	  grid_p->en_key_size = ksize;
	  grid_p->en_data = data;
	  grid_p->en_data_size = dsize;
	  
	  /* shift free list */
	  if (last_p == NULL) {
	    free_p = grid_p->en_next_p;
	  }
	  else {
	    last_p->en_next_p = grid_p->en_next_p;
	  }
	  grid_p->en_next_p = NULL;
	  free_c--;
	  iter_c++;
	}
	else {
	  for (grid_p = grid; grid_p < grid + MAX_ENTRIES; grid_p++) {
	    if (grid_p->en_free_b) {
	      continue;
	    }
	    if (grid_p->en_key_size == ksize
		&& memcmp(grid_p->en_key, key, ksize) == 0) {
	      break;
	    }
	  }
	  
	  /* if we did not store it then error */
	  if (grid_p >= grid + MAX_ENTRIES) {
	    (void)fprintf(stderr, "ERROR storing #%d: %s\n",
			  which, table_strerror(ret));
	  }
	  if (key != NULL) {
	    free(key);
	  }
	  if (data != NULL) {
	    free(data);
	  }
	}
      }
      break;
      
    case MODE_OVERWRITE:
      if (mmaping_b) {
	continue;
      }
      if (free_c < MAX_ENTRIES) {
	which = RANDOM_VALUE(MAX_ENTRIES);
	
	if (grid[which].en_free_b) {
	  continue;
	}
	
	data = random_block(&dsize);
	
	call_c++;
	ret = table_insert(tab_p, grid[which].en_key, grid[which].en_key_size,
			   data, dsize, NULL, 1);
	if (ret == TABLE_ERROR_NONE) {
	  if (verbose_b) {
	    (void)printf("overwrite pos %d with data of %d bytes\n",
			 which, dsize);
	    fflush(stdout);
	  }
	  grid[which].en_free_b = 0;
	  if (grid[which].en_data != NULL) {
	    free(grid[which].en_data);
	  }
	  grid[which].en_data = data;
	  grid[which].en_data_size = dsize;
	  grid[which].en_next_p = NULL;
	  free_c--;
	  iter_c++;
	}
	else {
	  (void)fprintf(stderr, "ERROR overwriting #%d: %s\n",
			which, table_strerror(ret));
	  free(data);
	}
      }
      break;
      
    case MODE_RETRIEVE:
      if (free_c < MAX_ENTRIES) {
	which = RANDOM_VALUE(MAX_ENTRIES);
	
	if (grid[which].en_free_b) {
	  continue;
	}
	
	call_c++;
	ret = table_retrieve(tab_p, grid[which].en_key, grid[which].en_key_size,
			     (void **)&data, &dsize);
	if (ret == TABLE_ERROR_NONE) {
	  if (grid[which].en_data_size == dsize
	      && memcmp(grid[which].en_data, data, dsize) == 0) {
	    if (verbose_b) {
	      (void)printf("retrieved key #%d, got data of %d bytes\n",
			   which, dsize);
	      fflush(stdout);
	    }
	  }
	  else {
	    (void)fprintf(stderr,
			  "ERROR: retrieve key #%d: data (%d bytes) didn't "
			  "match table (%d bytes)\n",
			  which, grid[which].en_data_size, dsize);
	  }
	  iter_c++;
	}
	else {
	  (void)fprintf(stderr, "error retrieving key #%d: %s\n",
			which, table_strerror(ret));
	}
      }
      break;
      
    case MODE_DELETE:
      if (mmaping_b) {
	continue;
      }
      if (free_c >= MAX_ENTRIES) {
	continue;
      }
      
      which = RANDOM_VALUE(MAX_ENTRIES);
      
      if (grid[which].en_free_b) {
	continue;
      }
      
      call_c++;
      ret = table_delete(tab_p, grid[which].en_key, grid[which].en_key_size,
			 (void **)&data, &dsize);
      if (ret == TABLE_ERROR_NONE) {
	if (grid[which].en_data_size == dsize
	    && memcmp(grid[which].en_data, data, dsize) == 0) {
	  if (verbose_b) {
	    (void)printf("deleted key #%d, got data of %d bytes\n",
			 which, dsize);
	    fflush(stdout);
	  }
	}
	else {
	  (void)fprintf(stderr,
			"ERROR deleting key #%d: data didn't match table\n",
			which);
	}
	grid[which].en_free_b = 1;
	if (grid[which].en_key != NULL) {
	  free(grid[which].en_key);
	}
	if (grid[which].en_data != NULL) {
	  free(grid[which].en_data);
	}
	grid[which].en_next_p = free_p;
	free_p = grid + which;
	free_c++;
	if (free_c == MAX_ENTRIES) {
	  linear_b = 0;
	  linear_eof_b = 0;
	}
	iter_c++;
	if (data != NULL) {
	  free(data);
	}
      }
      else {
	(void)fprintf(stderr, "ERROR deleting key %d: %s\n",
		      which, table_strerror(ret));
      }
      break;
      
    case MODE_DELETE_FIRST:
      /*
       * We have a problem here.  This is the only action routine
       * which modifies the table and is not key based.  We don't have
       * a way of looking up the key in our local data structure.
       */
      break;
      
    case MODE_FIRST:
      call_c++;
      ret = table_first(tab_p, (void **)&key, &ksize, (void **)&data, &dsize);
      if (ret == TABLE_ERROR_NONE) {
	linear_b = 1;
	linear_eof_b = 0;
	if (verbose_b) {
	  (void)printf("first entry has key, data of %d, %d bytes\n",
		       ksize, dsize);
	  fflush(stdout);
	}
	iter_c++;
      }
      else if (free_c == MAX_ENTRIES) {
	if (verbose_b) {
	  (void)printf("no first in table\n");
	  fflush(stdout);
	}
      }
      else {
	(void)fprintf(stderr, "ERROR: first in table: %s\n",
		      table_strerror(ret));
      }
      break;
      
    case MODE_NEXT:
      call_c++;
      ret = table_next(tab_p, (void **)&key, &ksize, (void **)&data, &dsize);
      if (ret == TABLE_ERROR_NONE) {
	if (verbose_b) {
	  (void)printf("next entry has key, data of %d, %d\n",
		       ksize, dsize);
	  fflush(stdout);
	}
	iter_c++;
      }
      else if (ret == TABLE_ERROR_LINEAR && (! linear_b)) {
	if (verbose_b) {
	  (void)printf("no first command run yet\n");
	  fflush(stdout);
	}
      }
      else if (ret == TABLE_ERROR_NOT_FOUND) {
	if (verbose_b) {
	  (void)printf("reached EOF with next in table: %s\n",
		       table_strerror(ret));
	  fflush(stdout);
	}
	linear_b = 0;
	linear_eof_b = 1;
      }
      else {
	(void)fprintf(stderr, "ERROR: table_next reports: %s\n",
		      table_strerror(ret));
	linear_b = 0;
	linear_eof_b = 0;
      }
      break;
      
    case MODE_THIS:
      call_c++;
      ret = table_this(tab_p, (void **)&key, &ksize, (void **)&data, &dsize);
      if (ret == TABLE_ERROR_NONE) {
	if (verbose_b) {
	  (void)printf("this entry has key,data of %d, %d bytes\n",
		       ksize, dsize);
	  fflush(stdout);
	}
	iter_c++;
      }
      else if (ret == TABLE_ERROR_LINEAR && (! linear_b)) {
	if (verbose_b) {
	  (void)printf("no first command run yet\n");
	  fflush(stdout);
	}
      }
      else if (ret == TABLE_ERROR_NOT_FOUND || linear_eof_b) {
	if (verbose_b) {
	  (void)printf("table linear already reached EOF\n");
	  fflush(stdout);
	}
      }
      else {
	(void)fprintf(stderr, "ERROR: this table: %s\n", table_strerror(ret));
	linear_b = 0;
	linear_eof_b = 0;
      }
      break;
      
    case MODE_INFO:
      {
	int	buckets, entries;
	
	call_c++;
	ret = table_info(tab_p, &buckets, &entries);
	if (ret == TABLE_ERROR_NONE) {
	  if (verbose_b) {
	    (void)printf("table has %d buckets, %d entries\n",
			 buckets, entries);
	    fflush(stdout);
	  }
	  iter_c++;
	}
	else {
	  (void)fprintf(stderr, "ERROR: table info: %s\n",
			table_strerror(ret));
	}
      }
    break;
    
    case MODE_ADJUST:
      {
	int	buckets, entries;
	
	if (mmaping_b || auto_adjust_b || large_b) {
	  continue;
	}
	
	call_c++;
	ret = table_info(tab_p, &buckets, &entries);
	if (ret == TABLE_ERROR_NONE) {
	  if (entries == 0) {
	    if (verbose_b) {
	      (void)printf("cannot adjusted table, %d entries\n", entries);
	      fflush(stdout);
	    }
	  }
	  else if (buckets == entries) {
	    if (verbose_b) {
	      (void)printf("no need to adjust table, %d buckets and entries\n",
			   buckets);
	      fflush(stdout);
	    }
	  }
	  else {
	    ret = table_adjust(tab_p, entries);
	    if (ret == TABLE_ERROR_NONE) {
	      (void)printf("adjusted table from %d to %d buckets\n",
			   buckets, entries);
	      iter_c++;
	    }
	    else {
	      (void)printf("ERROR: table adjust to %d buckets: %s\n",
			   entries, table_strerror(ret));
	    }
	  }
	}
	else {
	  (void)fprintf(stderr, "ERROR: table info: %s\n",
			table_strerror(ret));
	}
      }
      break;
      
    default:
      (void)printf("unknown mode %d\n", which);
      break;
    }
  }
  
  /* run through the grid and free the entries */
  for (grid_p = grid; grid_p < grid + MAX_ENTRIES; grid_p++) {
    if (! grid_p->en_free_b) {
      if (grid_p->en_key != NULL) {
	free(grid_p->en_key);
      }
      if (grid_p->en_data != NULL) {
	free(grid_p->en_data);
      }
    }
  }
  
  /* free used pointers */
  free(grid);
}
Exemple #8
0
int	main(int argc, char ** argv)
{
  table_t	*tab;
  int		ret, iter_n = ITERATIONS, alignment = 0;
  long		seed;
  
  argc--, argv++;
  
  /* set default seed */
  seed = time(NULL);
  
  /* process the args */
  for (; *argv != NULL; argv++, argc--) {
    if (**argv != '-') {
      continue;
    }
    
    switch (*(*argv + 1)) {
      
    case 'a':
      auto_adjust_b = 1;
      break;
      
    case 'A':
      if (argc > 0) {
	argv++, argc--;
	if (argc == 0) {
	  usage();
	}
	alignment = atoi(*argv);
      }
      break;
      
    case 'i':
      if (argc > 0) {
	argv++, argc--;
	if (argc == 0) {
	  usage();
	}
	iter_n = atoi(*argv);
      }
      break;
      
    case 'l':
      large_b = 1;
      break;
      
    case 's':
      if (argc > 0) {
	argv++, argc--;
	if (argc == 0) {
	  usage();
	}
	seed = atol(*argv);
      }
      break;
      
    case 'v':
      verbose_b = 1;
      break;
      
    default:
      usage();
      break;
    }
  }
  
  if (argc > 0) {
    usage();
  }
  
  (void)srandom(seed);
  (void)printf("Seed for random is %ld\n", seed);
  
  /* alloc the test table */
  call_c++;
  tab = table_alloc(0, &ret);
  if (tab == NULL) {
    (void)printf("table_alloc returned: %s\n", table_strerror(ret));
    exit(1);
  }
  
  if (auto_adjust_b) {
    ret = table_attr(tab, TABLE_FLAG_AUTO_ADJUST);
    if (ret != TABLE_ERROR_NONE) {
      (void)fprintf(stderr, "ERROR: could not set table for auto-adjust: %s\n",
		    table_strerror(ret));
      exit(1);
    }
  }
  
  if (alignment > 0) {
    ret = table_set_data_alignment(tab, alignment);
    if (ret != TABLE_ERROR_NONE) {
      (void)fprintf(stderr, "ERROR: could not set data alignment to %d: %s\n",
		    alignment, table_strerror(ret));
      exit(1);
    }
  }
  
  basic(tab);
  stress(tab, iter_n, 0);
  io_test(tab);
  order_test(tab);
  
  call_c++;
  ret = table_free(tab);
  if (ret != TABLE_ERROR_NONE) {
    (void)fprintf(stderr, "ERROR in table_free: %s\n", table_strerror(ret));
  }
  
  (void)fputc('\n', stdout);
  (void)printf("Test program performed %d table calls\n", call_c);
  
  exit(0);
}
void ssl_scache_shmht_init(server_rec *s, apr_pool_t *p)
{
    SSLModConfigRec *mc = myModConfig(s);
    table_t *ta;
    int ta_errno;
    apr_size_t avail;
    int n;
    apr_status_t rv;

    /*
     * Create shared memory segment
     */
    if (mc->szSessionCacheDataFile == NULL) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                     "SSLSessionCache required");
        ssl_die();
    }

    if ((rv = apr_shm_create(&(mc->pSessionCacheDataMM), 
                   mc->nSessionCacheDataSize, 
                   mc->szSessionCacheDataFile, mc->pPool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                     "Cannot allocate shared memory");
        ssl_die();
    }

    if ((rv = apr_rmm_init(&(mc->pSessionCacheDataRMM), NULL,
                   apr_shm_baseaddr_get(mc->pSessionCacheDataMM),
                   mc->nSessionCacheDataSize, mc->pPool)) != APR_SUCCESS) {
        ap_log_error(APLOG_MARK, APLOG_ERR, rv, s,
                     "Cannot initialize rmm");
        ssl_die();
    }
    ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                 "initialize MM %pp RMM %pp",
                 mc->pSessionCacheDataMM, mc->pSessionCacheDataRMM);

    /*
     * Create hash table in shared memory segment
     */
    avail = mc->nSessionCacheDataSize;
    n = (avail/2) / 1024;
    n = n < 10 ? 10 : n;

    /*
     * Passing server_rec as opt_param to table_alloc so that we can do
     * logging if required ssl_util_table. Otherwise, mc is sufficient.
     */ 
    if ((ta = table_alloc(n, &ta_errno, 
                          ssl_scache_shmht_malloc,  
                          ssl_scache_shmht_calloc, 
                          ssl_scache_shmht_realloc, 
                          ssl_scache_shmht_free, s )) == NULL) {
        ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
                     "Cannot allocate hash table in shared memory: %s",
                     table_strerror(ta_errno));
        ssl_die();
    }

    table_attr(ta, TABLE_FLAG_AUTO_ADJUST|TABLE_FLAG_ADJUST_DOWN);
    table_set_data_alignment(ta, sizeof(char *));
    table_clear(ta);
    mc->tSessionCacheDataTable = ta;

    /*
     * Log the done work
     */
    ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, 
                 "Init: Created hash-table (%d buckets) "
                 "in shared memory (%" APR_SIZE_T_FMT 
                 " bytes) for SSL session cache",
                 n, avail);
    return;
}