Esempio n. 1
0
// ML : cache * string -> string_ptr
String
apsml_cacheGet (Region rAddr, cache *c, String key1, request_data *rd)	/*{{{ */
{
//  ap_log_error(APLOG_MARK, LOG_DEBUG, 0, rd->server, "apsml_cacheGet 1");
//  ppCache (c, rd);

//  keyNhash kn;
  char *key = &(key1->data);
//  kn.hash = charhashfunction (kn.key);
//  ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
//		"apsml_cacheGet: key == %s, hash: %i", kn.key, kn.hash);
  int too_old = 0;
  apr_thread_rwlock_rdlock (c->rwlock);
  apr_proc_mutex_lock(rd->ctx->cachelock.plock);
  unsigned long cachehash = c->hashofname % rd->ctx->cachelock.shmsize;
  unsigned long cacheversion = rd->ctx->cachelock.version[cachehash];
  apr_proc_mutex_unlock(rd->ctx->cachelock.plock);

//  ap_log_error(APLOG_MARK, LOG_DEBUG, 0, rd->server, 
//          "apsml_cacheGet global version: %d, local version %d", cacheversion, c->version);

  if (cacheversion != c->version)
  {
    apr_thread_rwlock_unlock (c->rwlock);
    apsml_cacheFlush(c, rd, 0);
    c->version = cacheversion;
    return (String) NULL;
  }
  entry *entry;
//  void **entry1 = (void **) &entry;
  if (entrytable_find (c->htable, key, &entry) == hash_DNE)
  {
    entry = NULL;
//    ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
//	   "apsml_cacheGet: No such thing");
  }
  if (entry)
  {
    // we found an entry 
    // which should be put on top of the list
    // We require locking on the list
    // If time is too old then drop the entry

    time_t ct = time (NULL);
    apr_thread_mutex_lock (c->mutex);

    LINKEDLIST_REMOVE (entry);
    //time_t t = ct < entry->time ? 0 : ct - entry->time;
    if (entry->timeout)
    {
      if (ct > entry->time)
	    {			// entry too old
	      too_old = 1;
	     /* ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
			    "apsml_cacheGet: Entry too old, ct == %ld, entry->time == %ld",
			    ct, entry->time); */
	      LINKEDLIST_INSERTOVER (c->sentinel, entry);
	    }
      else
	    {
	      // keep entry fresh
	      LINKEDLIST_INSERTUNDER (c->sentinel, entry);
//	      ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
//			    "apsml_cacheGet: Entry fine ct == %i, entry->time == %i",
//			    ct, entry->time);
        cacheheap_heapchangekey(c->heap, entry->heappos, MAX (ct + entry->timeout, entry->time));
	      //entry->time = MAX (ct + entry->timeout, entry->time);
	    }
	  }
    else
    {
	    LINKEDLIST_INSERTUNDER (c->sentinel, entry);
    }
//    ap_log_rerror(APLOG_MARK, LOG_NOTICE, 0, rd->request, "apsml_cacheGetFound: etime: %d, rtime: %d, too_old: %i key: %s, value %d, valuedata: %s", entry->time, time(NULL), too_old, key, entry, entry->data);
     apr_thread_mutex_unlock (c->mutex);
  }
  String s;
  if (too_old == 0 && entry)
  {
    s = convertStringToML (rAddr, entry->data);
  }
  else
  {
    s = (String) NULL;
  }
  apr_thread_rwlock_unlock (c->rwlock);
//    ap_log_rerror(APLOG_MARK, LOG_NOTICE, 0, rd->request, "apsml_cacheGet: Returning");
  return s;
}				/*}}} */
Esempio n. 2
0
// ML: cache * String * String -> (int * string_ptr)
int
apsml_cacheSet (int resultPair, Region sAddr, cache * c, int keyValPair, request_data * rd)	/*{{{ */
{
  // allocate new entry and key,value placeholders
// ppCache(c, rd);
  String key1 = (String) elemRecordML (keyValPair, 0);
  String value1 = (String) elemRecordML (keyValPair, 1);
  time_t timeout = (time_t) elemRecordML (keyValPair, 2);
  char *value = &(value1->data);
  int valuesize = sizeStringDefine(value1);
  char *key = &(key1->data);
  int keysize = sizeStringDefine(key1);
  int size = sizeof (entry) + keysize + 1 + valuesize + 1;
  entry *newentry =
    (entry *) malloc (size);
//      ap_log_error (APLOG_MARK, LOG_DEBUG, 0, rd->server,
//		    "apsml_cacheCreate: malloc 0x%x, length: %d, sizeof(entry): %d, keysize: %d, valuesize: %d, key: %s, val: %s", (unsigned long) newentry, size, sizeof(entry), keysize, valuesize, key, value);
  if (newentry == NULL)
    return 0;
  char *newkey = (char *) (newentry + 1);
  char *newvalue = newkey + (keysize + 1);

  // prepare entry by copy data to my space and set pointers
  strncpy (newkey, key, keysize);
  newkey[keysize] = 0;
  strncpy (newvalue, value, valuesize);
  newvalue[valuesize] = 0;
  newentry->key = newkey;
//  newentry->key.hash = charhashfunction (newkey);
  newentry->data = newvalue;
  newentry->size = keysize + valuesize + sizeof (entry) + 2;
  time_t ct = time (NULL);
  if (timeout && c->timeout)
  {
    newentry->timeout = MIN (timeout, c->timeout);
  }
  else if (timeout)
  {
    newentry->timeout = timeout;
  }
  else
  {
    newentry->timeout = c->timeout;
  }
  newentry->time = ct + newentry->timeout;

  // We are going in !!! (as we get a writes lock we have 
  // complete control [no more locks])
  apr_thread_rwlock_wrlock (c->rwlock);
  int tmpsize = c->htable->hashTableSize;
  entry *oldentry = NULL;
//  void **oldentry1 = (void **) &oldentry;
//  ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
//		"apsml_cacheSet: key %s, hash: %i", key, newentry->key.hash);
  if (entrytable_find (c->htable, newentry->key, &oldentry) == hash_DNE)
  {
    // No old entry with that key 
    if ((newentry->timeout == -1 
            && cacheheap_heapinsert(c->heap, newentry, (time_t) 0) == heap_OUTOFMEM) 
        || (newentry->timeout && newentry->timeout != (time_t) -1
            && cacheheap_heapinsert(c->heap, newentry, newentry->time) == heap_OUTOFMEM))
    {
      ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
        "apsml_cacheSet: pid %d, received heap_OUTOFMEM", rd->ctx->pid);
      free(newentry);
      newentry = 0;
    }
    if (newentry && entrytable_insert (c->htable, newentry->key, newentry) == hash_OUTOFMEM)
	  {
      ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
        "apsml_cacheSet: pid %d, received hash_OUTOFMEM", rd->ctx->pid);
	    free (newentry);
	    newentry = 0;
	  }
//  ppCache(c, rd);
    oldentry = 0;
  }
  else
  {
    // Old exists
    if ((newentry->timeout == (time_t) -1 
           && cacheheap_heapinsert(c->heap, newentry, (time_t) 0) == heap_OUTOFMEM)
        || (newentry->timeout && newentry->timeout != (time_t) -1
           && cacheheap_heapinsert(c->heap, newentry, newentry->time) == heap_OUTOFMEM))
    {
      ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
        "apsml_cacheSet: pid %d, received heap_OUTOFMEM", rd->ctx->pid);
      free(newentry);
      newentry = 0;
    }
    if (newentry && entrytable_update (c->htable, newentry->key, newentry) == hash_OUTOFMEM)
	  {
      ap_log_error (APLOG_MARK, LOG_NOTICE, 0, rd->server,
        "apsml_cacheSet: pid %d, received hash_OUTOFMEM", rd->ctx->pid);
	    free (newentry);
	    newentry = 0;
	  }
  }

  if (newentry)
  {
    c->size += newentry->size;
    c->size += (tmpsize - c->htable->hashTableSize) * sizeof (entrytable_hashelement_t);
  }
//  ppCache(c, rd);
  int too_old = 0;
  if (oldentry)
  {
    // Old entry needs removel
    // time_t t = (ct - oldentry->time) < 0 ? 0 : ct - oldentry->time;
    if (oldentry->timeout && ct > oldentry->time)
	  {
	    too_old = 1;
	    second (resultPair) = 0;
	  }
    else
    {
      second (resultPair) = (int) convertStringToML (sAddr, oldentry->data);
    }
    listremoveitem (c, oldentry, rd);
  }
  if (too_old)
    oldentry = 0;
  if (newentry)
    LINKEDLIST_INSERTUNDER (c->sentinel, newentry);
  // I think we are done now
//  ppCache(c, rd);
  entry *curentry;
//  ap_log_error(APLOG_MARK, LOG_NOTICE, 0, rd->server, 
//          "apsml_cacheSet: size %d, maxsize = %d, ct: %d", c->size, c->maxsize, ct);
  while (cacheheap_heapminimal(c->heap, &curentry) != heap_UNDERFLOW)
  {
    if (curentry->time < ct)
    {
      cacheremoveitem(c, curentry, rd);
    }
    else break;
  }
//  ppCache(c, rd);
  if (c->maxsize != -1)
  {
    while (c->size > c->maxsize)
    {
      curentry = c->sentinel->up;
      if (curentry == c->sentinel)
        break;
      cacheremoveitem (c, curentry, rd);
    }
  }
  apr_thread_rwlock_unlock (c->rwlock);
//  ppCache(c, rd);
  if (oldentry && newentry)
    {
      first (resultPair) = 1;
      return resultPair;
    }
  second (resultPair) = 0;
  if (newentry)
    {
      first (resultPair) = 2;
      return resultPair;
    }
  first (resultPair) = 0;
  return resultPair;
}				/*}}} */
Esempio n. 3
0
static uintptr_t *
apdns_getFQDN_MX_1 (Region rAddrLPairs, Region rAddrEPairs,
		    Region rAddrString, char *str, uintptr_t *list, int depth, request_data *rd)
{
  if (depth < 0)
    return list;
  // i,j are used as loop counters
  // the dnspackage returned from the resolver is scanned from top to buttom
  // next is the package pointer relative to the start of the package
  int j, next;
  char ans[NS_PACKETSZ + 1];
  char dnsnamesa[NS_MAXDNAME];
  char *dnsnames = dnsnamesa;
  char *input = str;
  uintptr_t *pair, *listpair;
  String rs;
  dnshead *head = (dnshead *) ans;
  // get the dns package
  int n = res_search (input, C_IN, T_MX, (unsigned char *) ans, NS_PACKETSZ + 1);
  input = 0;
  if (n == -1)
    return list;
  if (n < sizeof (dnshead))
    return list;
  ntohhead (ans, head);
  if ((head->flags & 0xF) != 0)
    return list;
  if (head->anscount < 1)
    return list;
  // skip questions
  next = NS_HFIXEDSZ;
  for (j = 0; j < head->questcount; j++)
    {
      next = skipname (ans, next, n);
      next = iflessthan (next + 4, n);
      if (next < 0)
	return list;
    }
  // The answers
  int rv;
  for (j = 0; j < head->anscount; j++)
    {
//      int a_name = next;
      if (next >= n)
	return list;
      next = skipname (ans, next, n);
      if (next + NS_RRFIXEDSZ >= n || next < 0)
	return list;
      uint16_t a_type = twocharto16 (ans[next], ans[next + 1]);
      next += 4;
      uint32_t a_ttl =
	fourcharto32 (ans[next], ans[next + 1], ans[next + 2], ans[next + 3]);
      next += 4;
      uint16_t a_rdlength = twocharto16 (ans[next], ans[next + 1]);
      next += 2;
      if (a_type == T_MX)
	{			// We got a mx record
	  if (next + a_rdlength >= n || a_rdlength < 3)
	    return list;
	  uint16_t a_mx_pref = twocharto16 (ans[next], ans[next + 1]);
	  rv = dumpname (dnsnames, NS_MAXDNAME, ans, next + 2, n);
	  rs = convertStringToML (rAddrString, dnsnames);
	  allocRecordML (rAddrEPairs, 3, pair);
	  elemRecordML (pair, 0) = (uintptr_t) a_mx_pref;
	  elemRecordML (pair, 1) = (uintptr_t) a_ttl;
	  elemRecordML (pair, 2) = (uintptr_t) rs;
	  allocRecordML (rAddrLPairs, 2, listpair);
	  first (listpair) = (uintptr_t) pair;
	  second (listpair) = (uintptr_t) list;
	  makeCONS (listpair, list);
    ap_log_error (APLOG_MARK, LOG_DEBUG, 0, rd->server, 
        "apdns_getFQDN_MX: pref %i, ttl %i, %s", a_mx_pref, a_ttl, dnsnames);
	}
      else if (a_type == T_CNAME)
	{			// we got an alias (cononical name)
	  rv = dumpname (dnsnames, NS_MAXDNAME, ans, next, n);
	  input = dnsnames;
	  break;
	}
      else
	{			// we got something we did not ask for
	  // or cannot handle at the momnet
	  return list;
	}
      next += a_rdlength;
    }
  if (input)
    return apdns_getFQDN_MX_1 (rAddrLPairs, rAddrEPairs,
			       rAddrString, input, list, depth - 1, rd);
  return list;
}