static void
do_server_request(struct server *sv, int connfd)
{
	int ret;
	struct request *rq;
	struct file_data *data;
	data = file_data_init();	
	rq = request_init(connfd, data);
	
	if (!rq) {
		file_data_free(data);
		return;
	}
	
	if(cache_active ==1){
		pthread_mutex_lock( &conditionMutex); 
		struct hash_node *cache_stored; 
		cache_stored= cache_lookup(data->file_name);
		
		if(cache_stored!=NULL){  // check if it populated in the cache{
			data->file_buf = Malloc(cache_stored->data->file_size);
			strncpy(data->file_buf, cache_stored->data->file_buf, cache_stored->data->file_size);
			data->file_size =cache_stored->data->file_size;
		}
		else{
		/* reads file, 
	 	* fills data->file_buf with the file contents,
	 	* data->file_size with file size. */
	 	pthread_mutex_unlock( &conditionMutex ); 
		ret = request_readfile(rq);
		pthread_mutex_lock( &conditionMutex ); 
		// need to renew the cache
			if(data->file_size<max_cache){
				if(data->file_size <=(max_cache-cache_current_size) ){
					cache_insert(data);
				}
				else{
					cache_evict(data->file_size);
					cache_insert(data);
				}
			}
		}
		pthread_mutex_unlock( &conditionMutex ); 


	}	
	else{
		ret = request_readfile(rq);
		if (!ret)
		goto out;
	}
	/* sends file to client */
	request_sendfile(rq);
out:
	request_destroy(rq);
	file_data_free(data);
}
Beispiel #2
0
int
update_block_list(char *addr, int err_level)
{
    size_t addr_len = strlen(addr);

    if (cache_key_exist(block_list, addr, addr_len)) {
        int *count = NULL;
        cache_lookup(block_list, addr, addr_len, &count);
        if (count != NULL) {
            if (*count > MAX_TRIES)
                return 1;
            (*count) += err_level;
        }
    } else if (err_level > 0) {
        int *count = (int *)ss_malloc(sizeof(int));
        *count = 1;
        cache_insert(block_list, addr, addr_len, count);
#ifdef __linux__
        if (mode != NO_FIREWALL_MODE)
            set_firewall_rule(addr, 1);
#endif
    }

    return 0;
}
Beispiel #3
0
void memory_c::fill_queue() 
{

	/* For Lab #2, you need to fill out this function */ 
	/* CAUTION!: This function is not completed. Please complete this function */ 

	if (dram_out_queue.empty()) 
		return; 
	
	dram_out_queue.sort();
	mem_req_s *req = dram_out_queue.front(); 
	dram_out_queue.pop_front(); 

	/* insert into cache */
	cache_insert(data_cache,req->m_addr);

	/* search for matching mshr entry */ 
	m_mshr_entry_s *entry = search_matching_mshr(req->m_addr); 


	while(entry->req_ops.size())
	{
		Op *w_op = entry->req_ops.front();
		broadcast_rdy_op(w_op); 
		entry->req_ops.pop_front(); 
	}

	/* The following code will free mshr entry */ 
	list<m_mshr_entry_s *>::iterator mii = search_matching_mshr_itr(req->m_addr); 
	m_mshr.erase(mii); 

	free_mshr_entry(entry); 
  
}
Beispiel #4
0
void l2_cache_fill(int cpu_num, unsigned long long int addr, int set, int way, int prefetch, unsigned long long int evicted_addr)
{
  // uncomment this line to see the information available to you when there is a cache fill event
  //printf("0x%llx %d %d %d 0x%llx\n", addr, set, way, prefetch, evicted_addr);

  cache_insert(addr, prefetch);
  if (prefetch==1) {
    prefetch_tot_num++;


    // Insert Evicted address into pollution filter
    // only if it is not prefetch
    int found = cache_search(evicted_addr);
    if (found == -1) {
      if (evicted_addr != 0) {
      printf("ERROR: evicted address not in the cache - %llx \n", evicted_addr);
      exit(1);
      }
    }
    else 
      if (cache[found].pf != 1)
        poll_insert(evicted_addr);

    poll_remove(addr);
    
  }

  cache_remove(evicted_addr);
  
}
Beispiel #5
0
/*
 * When the local GSS-API library returns a single OID to the caller,
 * this gss_OID is assumed to be a pointer to stable storage, and need
 * not be freed by the caller.  We cannot return this structure directly
 * to the caller, since it is in the incorrect ABI.  (Neither can we
 * modify that stable storage directly, as it would break internal users
 * of the OID, violate the hosts alignment expectations, attempt a write
 * to immutable storage, or other bad things.)  We must return a translated
 * copy instead.  However, to retain the "caller does not free" property,
 * we must cache the values we hand out, and only ever allocate one OID
 * structure in the SAP ABI for any given OID.
 *
 * Returns 0 on success, and errno on failure.
 */
static int
gss_OID_loc_to_sap(gss_OID loc, sapgss_OID *sap)
{
    sapgss_OID s;
    int code;

    if (sap == NULL)
	return 0;
    if (loc == NULL) {
	*sap = NULL;
	return 0;
    }
    /* Try to find a cached copy to use. */
    s = cache_lookup(loc);

    if (s != NULL) {
	*sap = s;
	return 0;
    } /* else */

    /* Try to insert it into the cache.  Success here means that the next
     * lookup will succeed. */
    code = cache_insert(loc);
    if (code != 0) {
	*sap = NULL;
	return code;
    }
    *sap = cache_lookup(loc);
    return 0;
}
Beispiel #6
0
/*
 * load dri data
 *   type: data type
 *   no  : file no ( >= 0 )
 *   return: loaded dridata object
*/
dridata *ald_getdata(DRIFILETYPE type, int no) {
	dridata *ddata;
	
	/* check wrong request number */
	if (no < 0) return NULL;
	
	/* check wrong type */
	if (type >= DRIFILETYPEMAX) return NULL;
	
	/* check uninitilized data */
	if (dri[type] == NULL) return NULL;
	
	/* if mmapped */
	if (dri[type]->mmapped) return dri_getdata(dri[type], no);
	
	/* not mmapped */
	if (NULL == (ddata = (dridata *)cache_foreach(cacheid, (type << 16) + no))) {
		ddata = dri_getdata(dri[type], no);
		if (ddata != NULL) {
			cache_insert(cacheid, (type << 16) + no, (void *)ddata, ddata->size, &(ddata->in_use));
			ddata->in_use = TRUE;
		}
	}
	
	return ddata;
}
Beispiel #7
0
static int save_xbzrle_page(QEMUFile *f, uint8_t **current_data,
                            ram_addr_t current_addr, RAMBlock *block,
                            ram_addr_t offset, int cont, bool last_stage)
{
    int encoded_len = 0, bytes_sent = -1;
    uint8_t *prev_cached_page;

    if (!cache_is_cached(XBZRLE.cache, current_addr)) {
        acct_info.xbzrle_cache_miss++;
        if (!last_stage) {
            if (cache_insert(XBZRLE.cache, current_addr, *current_data) == -1) {
                return -1;
            } else {
                /* update *current_data when the page has been
                   inserted into cache */
                *current_data = get_cached_data(XBZRLE.cache, current_addr);
            }
        }
        return -1;
    }

    prev_cached_page = get_cached_data(XBZRLE.cache, current_addr);

    /* save current buffer into memory */
    memcpy(XBZRLE.current_buf, *current_data, TARGET_PAGE_SIZE);

    /* XBZRLE encoding (if there is no overflow) */
    encoded_len = xbzrle_encode_buffer(prev_cached_page, XBZRLE.current_buf,
                                       TARGET_PAGE_SIZE, XBZRLE.encoded_buf,
                                       TARGET_PAGE_SIZE);
    if (encoded_len == 0) {
        DPRINTF("Skipping unmodified page\n");
        return 0;
    } else if (encoded_len == -1) {
        DPRINTF("Overflow\n");
        acct_info.xbzrle_overflows++;
        /* update data in the cache */
        if (!last_stage) {
            memcpy(prev_cached_page, *current_data, TARGET_PAGE_SIZE);
            *current_data = prev_cached_page;
        }
        return -1;
    }

    /* we need to update the data in the cache, in order to get the same data */
    if (!last_stage) {
        memcpy(prev_cached_page, XBZRLE.current_buf, TARGET_PAGE_SIZE);
    }

    /* Send XBZRLE based compressed page */
    bytes_sent = save_block_hdr(f, block, offset, cont, RAM_SAVE_FLAG_XBZRLE);
    qemu_put_byte(f, ENCODING_FLAG_XBZRLE);
    qemu_put_be16(f, encoded_len);
    qemu_put_buffer(f, XBZRLE.encoded_buf, encoded_len);
    bytes_sent += encoded_len + 1 + 2;
    acct_info.xbzrle_pages++;
    acct_info.xbzrle_bytes += bytes_sent;

    return bytes_sent;
}
Beispiel #8
0
static void
client_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
    struct server_context *server = container_of(handle, struct server_context, udp);
    if (nread > 0) {
        char key[KEY_BYTES + 1] = {0};
        crypto_generickey((uint8_t *)key, sizeof(key) -1, (uint8_t*)addr, sizeof(*addr), NULL, 0);

        struct client_context *client = NULL;
        uv_mutex_lock(&mutex);
        cache_lookup(cache, key, (void *)&client);
        uv_mutex_unlock(&mutex);

        if (client == NULL) {
            client = new_client();
            client->addr = *addr;
            client->local_handle = handle;
            memcpy(client->key, key, sizeof(key));
            uv_timer_init(handle->loop, client->timer);
            uv_udp_init(handle->loop, &client->server_handle);
            client->server_handle.data = client;
            uv_udp_recv_start(&client->server_handle, server_alloc_cb, server_recv_cb);
            uv_mutex_lock(&mutex);
            cache_insert(cache, client->key, (void *)client);
            uv_mutex_unlock(&mutex);
        }

        int clen = nread + PRIMITIVE_BYTES + addrlen;
        int mlen = nread + addrlen;
        uint8_t *c = (uint8_t *)buf->base - PRIMITIVE_BYTES - addrlen;
        uint8_t *m = (uint8_t *)buf->base - addrlen;

        if (server->dest_addr->sa_family == AF_INET) {
            struct sockaddr_in *addr = (struct sockaddr_in *)server->dest_addr;
            m[0] = 1;
            memcpy(m + 1, &addr->sin_addr, 4);
            memcpy(m + 1 + 4, &addr->sin_port, 2);
        } else {
            struct sockaddr_in6 *addr = (struct sockaddr_in6 *)server->dest_addr;
            m[0] = 4;
            memcpy(m + 1, &addr->sin6_addr, 16);
            memcpy(m + 1 + 16, &addr->sin6_port, 2);
        }

        int rc = crypto_encrypt(c, m, mlen);
        if (!rc) {
            reset_timer(client);
            forward_to_server(server->server_addr, client, c, clen);
        }

    } else {
        goto error;
    }

    return;

error:
    free(buf->base - addrlen - PRIMITIVE_BYTES);
}
Beispiel #9
0
void cache_write(cache_m *scheduler, cache_n *node) 
{
    web_P(&scheduler->w);
    while (scheduler->total_size + node->size > MAX_CACHE_SIZE) {
	cache_remove(scheduler, scheduler->head.prev);
    }
    cache_insert(scheduler, node);
    web_V(&scheduler->w);
}
Beispiel #10
0
int64_t cache_resize(PageCache *cache, int64_t new_num_pages)
{
    PageCache *new_cache;
    int64_t i;

    CacheItem *old_it, *new_it;

    g_assert(cache);

    /* cache was not inited */
    if (cache->page_cache == NULL) {
        return -1;
    }

    /* same size */
    if (pow2floor(new_num_pages) == cache->max_num_items) {
        return cache->max_num_items;
    }

    new_cache = cache_init(new_num_pages, cache->page_size);
    if (!(new_cache)) {
        DPRINTF("Error creating new cache\n");
        return -1;
    }

    /* move all data from old cache */
    for (i = 0; i < cache->max_num_items; i++) {
        old_it = &cache->page_cache[i];
        if (old_it->it_addr != -1) {
            /* check for collision, if there is, keep MRU page */
            new_it = cache_get_by_addr(new_cache, old_it->it_addr);
            if (new_it->it_data) {
                /* keep the MRU page */
                if (new_it->it_age >= old_it->it_age) {
                    g_free(old_it->it_data);
                } else {
                    g_free(new_it->it_data);
                    new_it->it_data = old_it->it_data;
                    new_it->it_age = old_it->it_age;
                    new_it->it_addr = old_it->it_addr;
                }
            } else {
                cache_insert(new_cache, old_it->it_addr, old_it->it_data);
            }
        }
    }

    g_free(cache->page_cache);
    cache->page_cache = new_cache->page_cache;
    cache->max_num_items = new_cache->max_num_items;
    cache->num_items = new_cache->num_items;

    g_free(new_cache);

    return cache->max_num_items;
}
Beispiel #11
0
/* Update the xbzrle cache to reflect a page that's been sent as all 0.
 * The important thing is that a stale (not-yet-0'd) page be replaced
 * by the new data.
 * As a bonus, if the page wasn't in the cache it gets added so that
 * when a small write is made into the 0'd page it gets XBZRLE sent
 */
static void xbzrle_cache_zero_page(ram_addr_t current_addr)
{
    if (ram_bulk_stage || !migrate_use_xbzrle()) {
        return;
    }

    /* We don't care if this fails to allocate a new cache page
     * as long as it updated an old one */
    cache_insert(XBZRLE.cache, current_addr, ZERO_TARGET_PAGE);
}
Beispiel #12
0
static int idmap_lookup_group(
    struct idmap_context *context,
    const struct idmap_lookup *lookup,
    struct idmap_group *group)
{
    PCHAR* values[NUM_ATTRIBUTES] = { NULL };
    const unsigned attributes = ATTR_FLAG(ATTR_GROUP_NAME)
        | ATTR_FLAG(ATTR_GID);
    int i, status;

    /* check the group cache for an existing entry */
    status = cache_lookup(&context->groups, lookup, &group->entry);
    if (status == NO_ERROR) {
        /* don't return expired entries; query new attributes
         * and overwrite the entry with cache_insert() */
        if (time(NULL) - group->last_updated < context->config.cache_ttl)
            goto out;
    }

    /* send the query to the ldap server */
    status = idmap_query_attrs(context, lookup,
        attributes, 0, values, NUM_ATTRIBUTES);
    if (status)
        goto out_free_values;

    /* parse attributes */
    if (FAILED(StringCchCopyA(group->name, VAL_LEN,
            *values[ATTR_GROUP_NAME]))) {
        eprintf("ldap attribute %s='%s' longer than %u characters\n",
            context->config.attributes[ATTR_GROUP_NAME],
            *values[ATTR_GROUP_NAME], VAL_LEN);
        status = ERROR_BUFFER_OVERFLOW;
        goto out_free_values;
    }
    if (!parse_uint(*values[ATTR_GID], &group->gid)) {
        eprintf("failed to parse ldap attribute %s='%s'\n",
            context->config.attributes[ATTR_GID], *values[ATTR_GID]);
        status = ERROR_INVALID_PARAMETER;
        goto out_free_values;
    }
    group->last_updated = time(NULL);

    if (context->config.cache_ttl) {
        /* insert the entry into the cache */
        cache_insert(&context->groups, lookup, &group->entry);
    }
out_free_values:
    for (i = 0; i < NUM_ATTRIBUTES; i++)
        ldap_value_free(values[i]);
out:
    return status;
}
Beispiel #13
0
static struct file *
cache_get(const char *path)
{
  struct file *f = NULL;

  pthread_mutex_lock(&cache.lock);
  cache_clean();
  f = g_hash_table_lookup(cache.files, path);
  if(f == NULL)
    f = cache_insert(path);
  pthread_mutex_unlock(&cache.lock);

  return f;
}
Beispiel #14
0
/*
 *
 * SOCKS5 UDP Request
 * +----+------+------+----------+----------+----------+
 * |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
 * +----+------+------+----------+----------+----------+
 * | 2  |  1   |  1   | Variable |    2     | Variable |
 * +----+------+------+----------+----------+----------+
 *
 */
static void
client_recv_cb(uv_udp_t *handle, ssize_t nread, const uv_buf_t *buf, const struct sockaddr *addr, unsigned flags) {
    struct server_context *server = container_of(handle, struct server_context, udp);
    if (nread > 0) {
        uint8_t frag = buf->base[2];
        if (frag) {
            logger_log(LOG_ERR, "don't support udp dgram frag");
            goto err;
        }

        char key[KEY_BYTES + 1] = {0};
        crypto_generickey((uint8_t *)key, sizeof(key) -1, (uint8_t*)addr, sizeof(*addr), NULL, 0);

        struct client_context *client = NULL;
        uv_mutex_lock(&mutex);
        cache_lookup(cache, key, (void *)&client);
        uv_mutex_unlock(&mutex);

        if (client == NULL) {
            client = new_client();
            client->addr = *addr;
            client->local_handle = handle;
            memcpy(client->key, key, sizeof(key));
            uv_timer_init(handle->loop, client->timer);
            uv_udp_init(handle->loop, &client->server_handle);
            client->server_handle.data = client;
            uv_udp_recv_start(&client->server_handle, server_alloc_cb, server_recv_cb);
            uv_mutex_lock(&mutex);
            cache_insert(cache, client->key, (void *)client);
            uv_mutex_unlock(&mutex);
        }

        int clen = nread - 3 + PRIMITIVE_BYTES;
        uint8_t *c = (uint8_t *)buf->base - PRIMITIVE_BYTES;
        int rc = crypto_encrypt(c, (uint8_t*)buf->base + 3, nread - 3);
        if (!rc) {
            reset_timer(client);
            forward_to_server(server->server_addr, client, c, clen);
        }

    } else {
        goto err;
    }

    return;

err:
    free(buf->base - PRIMITIVE_BYTES);
}
Beispiel #15
0
int
check_block_list(char *addr, int err_level)
{
    size_t addr_len = strlen(addr);

    if (cache_key_exist(block_list, addr, addr_len)) {
        int *count = NULL;
        cache_lookup(block_list, addr, addr_len, &count);
        if (count != NULL) {
            if (*count > MAX_TRIES)
                return 1;
            (*count) += err_level;
        }
    } else {
        int *count = (int *)ss_malloc(sizeof(int));
        *count = 1;
        cache_insert(block_list, addr, addr_len, count);
    }

    return 0;
}
Beispiel #16
0
bool_t curl_op(char **arg, wd_in *result){
	CURL *curl;
	CURLcode res;
	wd_in wdi;
	char *url = arg[0];
	memset(&wdi, 0, sizeof(wdi));
	curl = curl_easy_init();
	if(NULL != curl) {
		curl_easy_setopt(curl, CURLOPT_URL, url);
		curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_data);
		curl_easy_setopt(curl, CURLOPT_WRITEDATA, &wdi);
		res = curl_easy_perform(curl);
		curl_easy_cleanup(curl);
		copy_result(&wdi,result);
		cache_insert(url, &wdi);
		return 1;
	}
	else {
		fprintf(stderr, "Error: could not get CURL handle.\n");
		return 0;
	}
}
Beispiel #17
0
static int rosedb_add(struct cache *cache, MDB_txn *txn, int argc, char *argv[])
{
	printf("ADD %s\t%s\t%s\t%s\t%s\t%s\n", argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]);

	knot_dname_t key[KNOT_DNAME_MAXLEN] = { '\0' };
	knot_dname_from_str(key, argv[0], sizeof(key));
	knot_dname_to_lower(key);

	struct entry entry;
	int ret = parse_rdata(&entry, argv[0], argv[1], argv[3], atoi(argv[2]), cache->pool);
	entry.threat_code = argv[4];
	entry.syslog_ip   = argv[5];
	if (ret != 0) {
		fprintf(stderr, "PARSE: %s\n", knot_strerror(ret));
		return ret;
	}

	ret = cache_insert(txn, cache->dbi, key, &entry);
	if (ret != 0) {
		fprintf(stderr, "%s\n", mdb_strerror(ret));
	}

	return ret;
}
Beispiel #18
0
struct peer_cache *rand_cache(struct peer_cache *c, int n)
{
  struct peer_cache *res;

cache_check(c);
  if (c->current_size < n) {
    n = c->current_size;
  }
  res = cache_init(n, c->metadata_size, c->max_timestamp);

  while(res->current_size < n) {
    int j;

    j = ((double)rand() / (double)RAND_MAX) * c->current_size;
    cache_insert(res, c->entries + j, c->metadata + c->metadata_size * j);
    c->current_size--;
    memmove(c->entries + j, c->entries + j + 1, sizeof(struct cache_entry) * (c->current_size - j));
    memmove(c->metadata + c->metadata_size * j, c->metadata + c->metadata_size * (j + 1), c->metadata_size * (c->current_size - j));
    c->entries[c->current_size].id = NULL;
cache_check(c);
  }

  return res;
}
/*
 *	Do caching checks.  Since we can update ANY VP list, we do
 *	exactly the same thing for all sections (autz / auth / etc.)
 *
 *	If you want to cache something different in different sections,
 *	configure another cache module.
 */
static rlm_rcode_t CC_HINT(nonnull) mod_cache_it(void *instance, REQUEST *request)
{
	rlm_cache_entry_t *c;
	rlm_cache_t *inst = instance;

	rlm_cache_handle_t *handle;

	vp_cursor_t cursor;
	VALUE_PAIR *vp;
	char buffer[1024];
	rlm_rcode_t rcode;

	int ttl = inst->ttl;

	if (radius_xlat(buffer, sizeof(buffer), request, inst->key, NULL, NULL) < 0) return RLM_MODULE_FAIL;

	if (buffer[0] == '\0') {
		REDEBUG("Zero length key string is invalid");
		return RLM_MODULE_INVALID;
	}

	if (cache_acquire(&handle, inst, request) < 0) return RLM_MODULE_FAIL;

	rcode = cache_find(&c, inst, request, &handle, buffer);
	if (rcode == RLM_MODULE_FAIL) goto finish;
	rad_assert(handle);

	/*
	 *	If Cache-Status-Only == yes, only return whether we found a
	 *	valid cache entry
	 */
	vp = pairfind(request->config_items, PW_CACHE_STATUS_ONLY, 0, TAG_ANY);
	if (vp && vp->vp_integer) {
		rcode = c ? RLM_MODULE_OK:
			    RLM_MODULE_NOTFOUND;
		goto finish;
	}

	/*
	 *	Update the expiry time based on the TTL.
	 *	A TTL of 0 means "delete from the cache".
	 *	A TTL < 0 means "delete from the cache and recreate the entry".
	 */
	vp = pairfind(request->config_items, PW_CACHE_TTL, 0, TAG_ANY);
	if (vp) ttl = vp->vp_signed;

	/*
	 *	If there's no existing cache entry, go and create a new one.
	 */
	if (!c) {
		if (ttl <= 0) ttl = inst->ttl;
		goto insert;
	}

	/*
	 *	Expire the entry if requested to do so
	 */
	if (vp) {
		if (ttl == 0) {
			cache_expire(inst, request, &handle, &c);
			RDEBUG("Forcing expiry of entry");
			rcode = RLM_MODULE_OK;
			goto finish;
		}

		if (ttl < 0) {
			RDEBUG("Forcing expiry of existing entry");
			cache_expire(inst, request, &handle, &c);
			ttl *= -1;
			goto insert;
		}
		c->expires = request->timestamp + ttl;
		RDEBUG("Setting TTL to %d", ttl);
	}

	/*
	 *	Cache entry was still valid, so we merge it into the request
	 *	and return. No need to add a new entry.
	 */
	cache_merge(inst, request, c);
	rcode = RLM_MODULE_UPDATED;

	goto finish;

insert:
	/*
	 *	If Cache-Read-Only == yes, then we only allow already cached entries
	 *	to be merged into the request
	 */
	vp = pairfind(request->config_items, PW_CACHE_READ_ONLY, 0, TAG_ANY);
	if (vp && vp->vp_integer) {
		rcode = RLM_MODULE_NOTFOUND;
		goto finish;
	}

	/*
	 *	Create a new entry.
	 */
	rcode = cache_insert(inst, request, &handle, buffer, ttl);
	rad_assert(handle);

finish:
	cache_free(inst, &c);
	cache_release(inst, request, &handle);

	/*
	 *	Clear control attributes
	 */
	for (vp = fr_cursor_init(&cursor, &request->config_items);
	     vp;
	     vp = fr_cursor_next(&cursor)) {
		if (vp->da->vendor == 0) switch (vp->da->attr) {
		case PW_CACHE_TTL:
		case PW_CACHE_STATUS_ONLY:
		case PW_CACHE_READ_ONLY:
		case PW_CACHE_MERGE:
			vp = fr_cursor_remove(&cursor);
			talloc_free(vp);
			break;
		}
	}

	return rcode;
}
Beispiel #20
0
static void
query_resolve_cb(struct sockaddr *addr, void *data)
{
    struct query_ctx *query_ctx = (struct query_ctx *)data;
    struct ev_loop *loop        = query_ctx->server_ctx->loop;

    if (verbose) {
        LOGI("[udp] udns resolved");
    }

    query_ctx->query = NULL;

    if (addr == NULL) {
        LOGE("[udp] udns returned an error");
    } else {
        remote_ctx_t *remote_ctx = query_ctx->remote_ctx;
        int cache_hit            = 0;

        // Lookup in the conn cache
        if (remote_ctx == NULL) {
            char *key = hash_key(AF_UNSPEC, &query_ctx->src_addr);
            cache_lookup(query_ctx->server_ctx->conn_cache, key, HASH_KEY_LEN, (void *)&remote_ctx);
        }

        if (remote_ctx == NULL) {
            int remotefd = create_remote_socket(addr->sa_family == AF_INET6);
            if (remotefd != -1) {
                setnonblocking(remotefd);
#ifdef SO_BROADCAST
                set_broadcast(remotefd);
#endif
#ifdef SO_NOSIGPIPE
                set_nosigpipe(remotefd);
#endif
#ifdef IP_TOS
                // Set QoS flag
                int tos = 46;
                setsockopt(remotefd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
#endif
#ifdef SET_INTERFACE
                if (query_ctx->server_ctx->iface) {
                    if (setinterface(remotefd, query_ctx->server_ctx->iface) == -1)
                        ERROR("setinterface");
                }
#endif
                remote_ctx                  = new_remote(remotefd, query_ctx->server_ctx);
                remote_ctx->src_addr        = query_ctx->src_addr;
                remote_ctx->server_ctx      = query_ctx->server_ctx;
                remote_ctx->addr_header_len = query_ctx->addr_header_len;
                memcpy(remote_ctx->addr_header, query_ctx->addr_header,
                       query_ctx->addr_header_len);
            } else {
                ERROR("[udp] bind() error");
            }
        } else {
            cache_hit = 1;
        }

        if (remote_ctx != NULL) {
            memcpy(&remote_ctx->dst_addr, addr, sizeof(struct sockaddr_storage));

            size_t addr_len = get_sockaddr_len(addr);
            int s           = sendto(remote_ctx->fd, query_ctx->buf->data, query_ctx->buf->len,
                                     0, addr, addr_len);

            if (s == -1) {
                ERROR("[udp] sendto_remote");
                if (!cache_hit) {
                    close_and_free_remote(EV_A_ remote_ctx);
                }
            } else {
                if (!cache_hit) {
                    // Add to conn cache
                    char *key = hash_key(AF_UNSPEC, &remote_ctx->src_addr);
                    cache_insert(query_ctx->server_ctx->conn_cache, key, HASH_KEY_LEN, (void *)remote_ctx);
                    ev_io_start(EV_A_ & remote_ctx->io);
                    ev_timer_start(EV_A_ & remote_ctx->watcher);
                }
            }
        }
    }

    // clean up
    close_and_free_query(EV_A_ query_ctx);
}
Beispiel #21
0
static void
server_recv_cb(EV_P_ ev_io *w, int revents)
{
    server_ctx_t *server_ctx = (server_ctx_t *)w;
    struct sockaddr_storage src_addr;
    memset(&src_addr, 0, sizeof(struct sockaddr_storage));

    buffer_t *buf = ss_malloc(sizeof(buffer_t));
    balloc(buf, buf_size);

    socklen_t src_addr_len = sizeof(struct sockaddr_storage);
    unsigned int offset    = 0;

#ifdef MODULE_REDIR
    char control_buffer[64] = { 0 };
    struct msghdr msg;
    memset(&msg, 0, sizeof(struct msghdr));
    struct iovec iov[1];
    struct sockaddr_storage dst_addr;
    memset(&dst_addr, 0, sizeof(struct sockaddr_storage));

    msg.msg_name       = &src_addr;
    msg.msg_namelen    = src_addr_len;
    msg.msg_control    = control_buffer;
    msg.msg_controllen = sizeof(control_buffer);

    iov[0].iov_base = buf->data;
    iov[0].iov_len  = buf_size;
    msg.msg_iov     = iov;
    msg.msg_iovlen  = 1;

    buf->len = recvmsg(server_ctx->fd, &msg, 0);
    if (buf->len == -1) {
        ERROR("[udp] server_recvmsg");
        goto CLEAN_UP;
    } else if (buf->len > packet_size) {
        if (verbose) {
            LOGI("[udp] UDP server_recv_recvmsg fragmentation");
        }
    }

    if (get_dstaddr(&msg, &dst_addr)) {
        LOGE("[udp] unable to get dest addr");
        goto CLEAN_UP;
    }

    src_addr_len = msg.msg_namelen;
#else
    ssize_t r;
    r = recvfrom(server_ctx->fd, buf->data, buf_size,
                 0, (struct sockaddr *)&src_addr, &src_addr_len);

    if (r == -1) {
        // error on recv
        // simply drop that packet
        ERROR("[udp] server_recv_recvfrom");
        goto CLEAN_UP;
    } else if (r > packet_size) {
        if (verbose) {
            LOGI("[udp] server_recv_recvfrom fragmentation");
        }
    }

    buf->len = r;
#endif

    if (verbose) {
        LOGI("[udp] server receive a packet");
    }

#ifdef MODULE_REMOTE
    tx += buf->len;

    int err = server_ctx->crypto->decrypt_all(buf, server_ctx->crypto->cipher, buf_size);
    if (err) {
        // drop the packet silently
        goto CLEAN_UP;
    }
#endif

#ifdef MODULE_LOCAL
#if !defined(MODULE_TUNNEL) && !defined(MODULE_REDIR)
#ifdef __ANDROID__
    tx += buf->len;
#endif
    uint8_t frag = *(uint8_t *)(buf->data + 2);
    offset += 3;
#endif
#endif

    /*
     *
     * SOCKS5 UDP Request
     * +----+------+------+----------+----------+----------+
     * |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
     * +----+------+------+----------+----------+----------+
     * | 2  |  1   |  1   | Variable |    2     | Variable |
     * +----+------+------+----------+----------+----------+
     *
     * SOCKS5 UDP Response
     * +----+------+------+----------+----------+----------+
     * |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
     * +----+------+------+----------+----------+----------+
     * | 2  |  1   |  1   | Variable |    2     | Variable |
     * +----+------+------+----------+----------+----------+
     *
     * shadowsocks UDP Request (before encrypted)
     * +------+----------+----------+----------+
     * | ATYP | DST.ADDR | DST.PORT |   DATA   |
     * +------+----------+----------+----------+
     * |  1   | Variable |    2     | Variable |
     * +------+----------+----------+----------+
     *
     * shadowsocks UDP Response (before encrypted)
     * +------+----------+----------+----------+
     * | ATYP | DST.ADDR | DST.PORT |   DATA   |
     * +------+----------+----------+----------+
     * |  1   | Variable |    2     | Variable |
     * +------+----------+----------+----------+
     *
     * shadowsocks UDP Request and Response (after encrypted)
     * +-------+--------------+
     * |   IV  |    PAYLOAD   |
     * +-------+--------------+
     * | Fixed |   Variable   |
     * +-------+--------------+
     *
     */

#ifdef MODULE_REDIR
    char addr_header[512] = { 0 };
    int addr_header_len   = construct_udprelay_header(&dst_addr, addr_header);

    if (addr_header_len == 0) {
        LOGE("[udp] failed to parse tproxy addr");
        goto CLEAN_UP;
    }

    // reconstruct the buffer
    brealloc(buf, buf->len + addr_header_len, buf_size);
    memmove(buf->data + addr_header_len, buf->data, buf->len);
    memcpy(buf->data, addr_header, addr_header_len);
    buf->len += addr_header_len;

#elif MODULE_TUNNEL

    char addr_header[512] = { 0 };
    char *host            = server_ctx->tunnel_addr.host;
    char *port            = server_ctx->tunnel_addr.port;
    uint16_t port_num     = (uint16_t)atoi(port);
    uint16_t port_net_num = htons(port_num);
    int addr_header_len   = 0;

    struct cork_ip ip;
    if (cork_ip_init(&ip, host) != -1) {
        if (ip.version == 4) {
            // send as IPv4
            struct in_addr host_addr;
            memset(&host_addr, 0, sizeof(struct in_addr));
            int host_len = sizeof(struct in_addr);

            if (dns_pton(AF_INET, host, &host_addr) == -1) {
                FATAL("IP parser error");
            }
            addr_header[addr_header_len++] = 1;
            memcpy(addr_header + addr_header_len, &host_addr, host_len);
            addr_header_len += host_len;
        } else if (ip.version == 6) {
            // send as IPv6
            struct in6_addr host_addr;
            memset(&host_addr, 0, sizeof(struct in6_addr));
            int host_len = sizeof(struct in6_addr);

            if (dns_pton(AF_INET6, host, &host_addr) == -1) {
                FATAL("IP parser error");
            }
            addr_header[addr_header_len++] = 4;
            memcpy(addr_header + addr_header_len, &host_addr, host_len);
            addr_header_len += host_len;
        } else {
            FATAL("IP parser error");
        }
    } else {
        // send as domain
        int host_len = strlen(host);

        addr_header[addr_header_len++] = 3;
        addr_header[addr_header_len++] = host_len;
        memcpy(addr_header + addr_header_len, host, host_len);
        addr_header_len += host_len;
    }
    memcpy(addr_header + addr_header_len, &port_net_num, 2);
    addr_header_len += 2;

    // reconstruct the buffer
    brealloc(buf, buf->len + addr_header_len, buf_size);
    memmove(buf->data + addr_header_len, buf->data, buf->len);
    memcpy(buf->data, addr_header, addr_header_len);
    buf->len += addr_header_len;

#else

    char host[257] = { 0 };
    char port[64]  = { 0 };
    struct sockaddr_storage dst_addr;
    memset(&dst_addr, 0, sizeof(struct sockaddr_storage));

    int addr_header_len = parse_udprelay_header(buf->data + offset, buf->len - offset,
                                                host, port, &dst_addr);
    if (addr_header_len == 0) {
        // error in parse header
        goto CLEAN_UP;
    }

    char *addr_header = buf->data + offset;
#endif

#ifdef MODULE_LOCAL
    char *key = hash_key(server_ctx->remote_addr->sa_family, &src_addr);
#else
    char *key = hash_key(dst_addr.ss_family, &src_addr);
#endif

    struct cache *conn_cache = server_ctx->conn_cache;

    remote_ctx_t *remote_ctx = NULL;
    cache_lookup(conn_cache, key, HASH_KEY_LEN, (void *)&remote_ctx);

    if (remote_ctx != NULL) {
        if (sockaddr_cmp(&src_addr, &remote_ctx->src_addr, sizeof(src_addr))) {
            remote_ctx = NULL;
        }
    }

    // reset the timer
    if (remote_ctx != NULL) {
        ev_timer_again(EV_A_ & remote_ctx->watcher);
    }

    if (remote_ctx == NULL) {
        if (verbose) {
#ifdef MODULE_REDIR
            char src[SS_ADDRSTRLEN];
            char dst[SS_ADDRSTRLEN];
            strcpy(src, get_addr_str((struct sockaddr *)&src_addr));
            strcpy(dst, get_addr_str((struct sockaddr *)&dst_addr));
            LOGI("[udp] cache miss: %s <-> %s", dst, src);
#else
            LOGI("[udp] cache miss: %s:%s <-> %s", host, port,
                 get_addr_str((struct sockaddr *)&src_addr));
#endif
        }
    } else {
        if (verbose) {
#ifdef MODULE_REDIR
            char src[SS_ADDRSTRLEN];
            char dst[SS_ADDRSTRLEN];
            strcpy(src, get_addr_str((struct sockaddr *)&src_addr));
            strcpy(dst, get_addr_str((struct sockaddr *)&dst_addr));
            LOGI("[udp] cache hit: %s <-> %s", dst, src);
#else
            LOGI("[udp] cache hit: %s:%s <-> %s", host, port,
                 get_addr_str((struct sockaddr *)&src_addr));
#endif
        }
    }

#ifdef MODULE_LOCAL

#if !defined(MODULE_TUNNEL) && !defined(MODULE_REDIR)
    if (frag) {
        LOGE("[udp] drop a message since frag is not 0, but %d", frag);
        goto CLEAN_UP;
    }
#endif

    const struct sockaddr *remote_addr = server_ctx->remote_addr;
    const int remote_addr_len          = server_ctx->remote_addr_len;

    if (remote_ctx == NULL) {
        // Bind to any port
        int remotefd = create_remote_socket(remote_addr->sa_family == AF_INET6);
        if (remotefd < 0) {
            ERROR("[udp] udprelay bind() error");
            goto CLEAN_UP;
        }
        setnonblocking(remotefd);

#ifdef SO_NOSIGPIPE
        set_nosigpipe(remotefd);
#endif
#ifdef IP_TOS
        // Set QoS flag
        int tos = 46;
        setsockopt(remotefd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
#endif
#ifdef SET_INTERFACE
        if (server_ctx->iface) {
            if (setinterface(remotefd, server_ctx->iface) == -1)
                ERROR("setinterface");
        }
#endif

#ifdef __ANDROID__
        if (vpn) {
            if (protect_socket(remotefd) == -1) {
                ERROR("protect_socket");
                close(remotefd);
                goto CLEAN_UP;
            }
        }
#endif

        // Init remote_ctx
        remote_ctx                  = new_remote(remotefd, server_ctx);
        remote_ctx->src_addr        = src_addr;
        remote_ctx->af              = remote_addr->sa_family;
        remote_ctx->addr_header_len = addr_header_len;
        memcpy(remote_ctx->addr_header, addr_header, addr_header_len);

        // Add to conn cache
        cache_insert(conn_cache, key, HASH_KEY_LEN, (void *)remote_ctx);

        // Start remote io
        ev_io_start(EV_A_ & remote_ctx->io);
        ev_timer_start(EV_A_ & remote_ctx->watcher);
    }

    if (offset > 0) {
        buf->len -= offset;
        memmove(buf->data, buf->data + offset, buf->len);
    }

    int err = server_ctx->crypto->encrypt_all(buf, server_ctx->crypto->cipher, buf_size);

    if (err) {
        // drop the packet silently
        goto CLEAN_UP;
    }

    if (buf->len > packet_size) {
        if (verbose) {
            LOGI("[udp] server_recv_sendto fragmentation");
        }
    }

    int s = sendto(remote_ctx->fd, buf->data, buf->len, 0, remote_addr, remote_addr_len);

    if (s == -1) {
        ERROR("[udp] server_recv_sendto");
    }

#else

    int cache_hit  = 0;
    int need_query = 0;

    if (buf->len - addr_header_len > packet_size) {
        if (verbose) {
            LOGI("[udp] server_recv_sendto fragmentation");
        }
    }

    if (remote_ctx != NULL) {
        cache_hit = 1;
        // detect destination mismatch
        if (remote_ctx->addr_header_len != addr_header_len
            || memcmp(addr_header, remote_ctx->addr_header, addr_header_len) != 0) {
            if (dst_addr.ss_family != AF_INET && dst_addr.ss_family != AF_INET6) {
                need_query = 1;
            }
        } else {
            memcpy(&dst_addr, &remote_ctx->dst_addr, sizeof(struct sockaddr_storage));
        }
    } else {
        if (dst_addr.ss_family == AF_INET || dst_addr.ss_family == AF_INET6) {
            int remotefd = create_remote_socket(dst_addr.ss_family == AF_INET6);
            if (remotefd != -1) {
                setnonblocking(remotefd);
#ifdef SO_BROADCAST
                set_broadcast(remotefd);
#endif
#ifdef SO_NOSIGPIPE
                set_nosigpipe(remotefd);
#endif
#ifdef IP_TOS
                // Set QoS flag
                int tos = 46;
                setsockopt(remotefd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos));
#endif
#ifdef SET_INTERFACE
                if (server_ctx->iface) {
                    if (setinterface(remotefd, server_ctx->iface) == -1)
                        ERROR("setinterface");
                }
#endif
                remote_ctx                  = new_remote(remotefd, server_ctx);
                remote_ctx->src_addr        = src_addr;
                remote_ctx->server_ctx      = server_ctx;
                remote_ctx->addr_header_len = addr_header_len;
                memcpy(remote_ctx->addr_header, addr_header, addr_header_len);
                memcpy(&remote_ctx->dst_addr, &dst_addr, sizeof(struct sockaddr_storage));
            } else {
                ERROR("[udp] bind() error");
                goto CLEAN_UP;
            }
        }
    }

    if (remote_ctx != NULL && !need_query) {
        size_t addr_len = get_sockaddr_len((struct sockaddr *)&dst_addr);
        int s           = sendto(remote_ctx->fd, buf->data + addr_header_len,
                                 buf->len - addr_header_len, 0,
                                 (struct sockaddr *)&dst_addr, addr_len);

        if (s == -1) {
            ERROR("[udp] sendto_remote");
            if (!cache_hit) {
                close_and_free_remote(EV_A_ remote_ctx);
            }
        } else {
            if (!cache_hit) {
                // Add to conn cache
                remote_ctx->af = dst_addr.ss_family;
                char *key = hash_key(remote_ctx->af, &remote_ctx->src_addr);
                cache_insert(server_ctx->conn_cache, key, HASH_KEY_LEN, (void *)remote_ctx);

                ev_io_start(EV_A_ & remote_ctx->io);
                ev_timer_start(EV_A_ & remote_ctx->watcher);
            }
        }
    } else {
        struct addrinfo hints;
        memset(&hints, 0, sizeof(struct addrinfo));
        hints.ai_family   = AF_UNSPEC;
        hints.ai_socktype = SOCK_DGRAM;
        hints.ai_protocol = IPPROTO_UDP;

        struct query_ctx *query_ctx = new_query_ctx(buf->data + addr_header_len,
                                                    buf->len - addr_header_len);
        query_ctx->server_ctx      = server_ctx;
        query_ctx->addr_header_len = addr_header_len;
        query_ctx->src_addr        = src_addr;
        memcpy(query_ctx->addr_header, addr_header, addr_header_len);

        if (need_query) {
            query_ctx->remote_ctx = remote_ctx;
        }

        struct ResolvQuery *query = resolv_query(host, query_resolve_cb,
                                                 NULL, query_ctx, htons(atoi(port)));
        if (query == NULL) {
            ERROR("[udp] unable to create DNS query");
            close_and_free_query(EV_A_ query_ctx);
            goto CLEAN_UP;
        }
        query_ctx->query = query;
    }
#endif

CLEAN_UP:
    bfree(buf);
    ss_free(buf);
}
Beispiel #22
0
//services the request from the queue
void * worker(void * arg)
{
    // assign a thread id
    pthread_mutex_lock(&threadnum_access);
    int thread_id = thread_num; // thread id (between 0 and n-1)
    thread_num++;
    pthread_mutex_unlock(&threadnum_access);
    
	unsigned char *buf = NULL;//data for file
	struct stat file_info;//struct where size is
	struct timespec t1, t2;//structs for time
    char time[100];//string for response time
    long time_diff;
    bool time_error = false;
	off_t file_size;//size of file
	int reqFd;//for the read file
    char log_entry[MAX_TEXT_SIZE];
    char* filename;
    char full_path[MAX_TEXT_SIZE];
    char* file_ending = malloc(sizeof(char) * MAX_REQUEST_LENGTH);
    char* content_type = malloc(sizeof(char) * MAX_REQUEST_LENGTH);
    char error_string[251];
    bool cache_hit = false;//true for hit false for miss
    int cache_index = -1;
    int fd;
    FILE *read_file;
    int request_count = 0; // how many requests this worker thread has completed
    int error_flag = 0;
    
    // continue this loop while either dispatchers left or requests in queue
    while (cur_num_dispatch > 0 || count > 0) {
        
        pthread_mutex_lock(&queue_access); 
        
        // wait only while dispatchers left and no requests in queue
        while (cur_num_dispatch > 0 && count == 0)
        {
            pthread_cond_wait(&queue_full_or_dispatch_exit, &queue_access);
        }
        
        count--;
        //get time 1 in nano seconds
    	if(clock_gettime(CLOCK_MONOTONIC, &t1) != 0)
		{
			perror("can't get time");
			strcpy(time,"ERROR");
			time_error = true;
		}
        filename = queue[r_queue_index].m_szRequest;
        fd = queue[r_queue_index].m_socket;
        if (get_type(filename, content_type) == -1)
        {
            printf("Failed to get content type.\n");
            strcpy(content_type, "Error");
            strcpy(error_string, "Could not get content type");
        }
        
        if (strcmp(content_type, "Error") == 0)
            error_flag = 1;
        else
            error_flag = 0;
        
        if (use_cache)
            cache_index = cache_search(filename, &file_size);
        
        if(cache_index >= 0)
        {
            if (return_result(fd, content_type, cache[cache_index].data, (int)cache[cache_index].file_size) != 0)
            {
                fprintf(stderr, "Failed to return result.\n");
            }
            else
            {
                //get time 2 in nano seconds
                if(clock_gettime(CLOCK_MONOTONIC, &t2) != 0)
                {
                    perror("can't get time");
                    strcpy(time,"ERROR");
                    time_error = true;
                }
                else
                {
                    time_diff = t2.tv_nsec = t1.tv_nsec;
                    time_diff = time_diff / NANO_TO_MILLI;
                    sprintf(time, "%ldms", time_diff);
                }
                cache_hit = true;
            }	
        }
        else//read from file
        {
	    	sprintf(full_path, "%s%s", path, filename);
		    
		    // open file, copy to buffer
		    if ((read_file = fopen(full_path, "r")) == NULL)
		    {
		        perror("Failed to open file");
		        strcpy(content_type, "Error");
		        strcpy(error_string,"could not open file");
		        error_flag = 1;
		    }
		    else//good read
		    {
		    	if(stat(full_path,&file_info) < 0)
		    	{
			        perror("Failed to get file size");
			        strcpy(content_type, "Error");
			        strcpy(error_string, "could not get file size");
			        error_flag = 1;
		    	}
		    	else//good stat
		    	{
		    		file_size = file_info.st_size;
        			if(buf == NULL)
        			{
        				buf = (unsigned char*)malloc((size_t)file_size);
        				if(buf == NULL)
        				{
        					perror("could not allocate memory");
        					strcpy(content_type, "Error");
        					strcpy(error_string,"could not allocate memory");
            				error_flag = 1;
        				}
        			}
        			else//realloc buf
        			{
        				buf = (unsigned char*)realloc(buf,(size_t)file_size);
        				if(buf == NULL)
        				{
        					perror("could not allocate memory");
        					strcpy(content_type, "Error");
        					strcpy(error_string,"could not allocate memory");
            				error_flag = 1;
        				}
        			}//end realloc
		    	}//end good stat
	    	}//end good read
	    	
	    	
	    	if(!error_flag)
	    	{
	    		if (fread(buf, 1, (size_t)file_size, read_file) <= 0)//sizeof(char)
		        {
		            printf("failed to read from file.");
		            strcpy(content_type, "Error");
		            strcpy(error_string,"could not read file");
		            error_flag = 1;
		        }
		        else
		        {
				    if (return_result(fd, content_type, buf, (int)file_size) != 0)
				    {
				        fprintf(stderr, "Failed to return result.\n");
				    }
				    else
				    {
    					if(clock_gettime(CLOCK_MONOTONIC, &t2) != 0)
						{
							perror("can't get time");
							strcpy(time,"ERROR");
							time_error = true;
						}
						else
						{
							time_diff = t2.tv_nsec = t1.tv_nsec;
							time_diff = time_diff / NANO_TO_MILLI;	
							sprintf(time,"%ldms",time_diff);
						}
				    }
				    if(use_cache && cache_insert(buf, filename, file_size) < 0)
				    {
				    	fprintf(stderr, "Failed to add file to cache\n");
				    }
		        }
	    	}
    	}//end read file
        if(error_flag)
        {
            if (return_error(fd, error_string) != 0)
            {
                fprintf(stderr, "Failed to return error.\n");
            }
        }
          
        r_queue_index = (r_queue_index + 1) % queue_length;
        
        pthread_mutex_unlock(&queue_access);
        pthread_cond_broadcast(&queue_empty);
        
        // log to file
        pthread_mutex_lock(&log_access);
        request_count++;
        
        if(cache_hit == true)
        {
        	sprintf(log_entry,"[%d][%d][%d][%s][%lu][%s][%s]\n",thread_id, request_count, fd, filename,(unsigned long)file_size,time,"HIT");
        	cache_hit = false;
        }
        else
        {
        	if(!error_flag)
        	{
                if (use_cache)
                    sprintf(log_entry,"[%d][%d][%d][%s][%lu][%s][%s]\n",thread_id, request_count, fd, filename,(unsigned long)file_size,time,"MISS");
                else
                    sprintf(log_entry,"[%d][%d][%d][%s][%lu]\n",thread_id, request_count, fd, filename,(unsigned long)file_size);
        	}
        	else
        	{
        		sprintf(log_entry,"[%d][%d][%d][%s][%s]\n",thread_id, request_count, fd, filename,error_string);
        	}
        }
    	
    	if(write(logFd,log_entry, strlen(log_entry)) < 0)
    		perror("failed to write to log");
        
        pthread_mutex_unlock(&log_access);
    }
    
    // no more dispatcher threads or requests, work has been completed
    free(filename);
    free(buf);
    free(file_ending);
    free(content_type);
    free(read_file);
    printf("Closing the log\n");
    pthread_exit(NULL);
    
    return NULL;
}
Beispiel #23
0
int ss_decrypt(buffer_t *cipher, enc_ctx_t *ctx, size_t capacity)
{
    if (ctx != NULL) {
        static buffer_t tmp = { 0, 0, 0, NULL };

        size_t iv_len = 0;
        int err       = 1;

        brealloc(&tmp, cipher->len, capacity);
        buffer_t *plain = &tmp;
        plain->len = cipher->len;

        if (!ctx->init) {
            uint8_t iv[MAX_IV_LENGTH];
            iv_len      = enc_iv_len;
            plain->len -= iv_len;

            memcpy(iv, cipher->array, iv_len);
            cipher_context_set_iv(&ctx->evp, iv, iv_len, 0);
            ctx->counter = 0;
            ctx->init    = 1;

            if (enc_method >= RC4_MD5) {
                if (cache_key_exist(iv_cache, (char *)iv, iv_len)) {
                    bfree(cipher);
                    return -1;
                } else {
                    cache_insert(iv_cache, (char *)iv, iv_len, NULL);
                }
            }
        }

        if (enc_method >= SALSA20) {
            int padding = ctx->counter % SODIUM_BLOCK_SIZE;
            brealloc(plain, (plain->len + padding) * 2, capacity);

            if (padding) {
                brealloc(cipher, cipher->len + padding, capacity);
                memmove(cipher->array + iv_len + padding, cipher->array + iv_len,
                        cipher->len - iv_len);
                memset(cipher->array + iv_len, 0, padding);
            }
            crypto_stream_xor_ic((uint8_t *)plain->array,
                                 (const uint8_t *)(cipher->array + iv_len),
                                 (uint64_t)(cipher->len - iv_len + padding),
                                 (const uint8_t *)ctx->evp.iv,
                                 ctx->counter / SODIUM_BLOCK_SIZE, enc_key,
                                 enc_method);
            ctx->counter += cipher->len - iv_len;
            if (padding) {
                memmove(plain->array, plain->array + padding, plain->len);
            }
        } else {
            err = cipher_context_update(&ctx->evp, (uint8_t *)plain->array, &plain->len,
                                        (const uint8_t *)(cipher->array + iv_len),
                                        cipher->len - iv_len);
        }

        if (!err) {
            bfree(cipher);
            return -1;
        }

#ifdef DEBUG
        dump("PLAIN", plain->array, plain->len);
        dump("CIPHER", cipher->array + iv_len, cipher->len - iv_len);
#endif

        brealloc(cipher, plain->len, capacity);
        memcpy(cipher->array, plain->array, plain->len);
        cipher->len = plain->len;

        return 0;
    } else {
        char *begin = cipher->array;
        char *ptr   = cipher->array;
        while (ptr < begin + cipher->len) {
            *ptr = (char)dec_table[(uint8_t)*ptr];
            ptr++;
        }
        return 0;
    }
}
Beispiel #24
0
/*
  the main forward mapping function, which converts a long filename to 
  a 8.3 name

  if need83 is not set then we only do the mangling if the name is illegal
  as a long name

  if cache83 is not set then we don't cache the result

  return NULL if we don't need to do any conversion
*/
static char *name_map(struct pvfs_mangle_context *ctx,
		      const char *name, bool need83, bool cache83)
{
	char *dot_p;
	char lead_chars[7];
	char extension[4];
	unsigned int extension_length, i;
	unsigned int prefix_len;
	uint32_t hash, v;
	char *new_name;
	const char *basechars = MANGLE_BASECHARS;

	/* reserved names are handled specially */
	if (!is_reserved_name(ctx, name)) {
		/* if the name is already a valid 8.3 name then we don't need to 
		   do anything */
		if (is_8_3(ctx, name, false, false)) {
			return NULL;
		}

		/* if the caller doesn't strictly need 8.3 then just check for illegal 
		   filenames */
		if (!need83 && is_legal_name(ctx, name)) {
			return NULL;
		}
	}

	/* find the '.' if any */
	dot_p = strrchr(name, '.');

	if (dot_p) {
		/* if the extension contains any illegal characters or
		   is too long or zero length then we treat it as part
		   of the prefix */
		for (i=0; i<4 && dot_p[i+1]; i++) {
			if (! FLAG_CHECK(dot_p[i+1], FLAG_ASCII)) {
				dot_p = NULL;
				break;
			}
		}
		if (i == 0 || i == 4) dot_p = NULL;
	}

	/* the leading characters in the mangled name is taken from
	   the first characters of the name, if they are ascii otherwise
	   '_' is used
	*/
	for (i=0;i<ctx->mangle_prefix && name[i];i++) {
		lead_chars[i] = name[i];
		if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) {
			lead_chars[i] = '_';
		}
		lead_chars[i] = toupper((unsigned char)lead_chars[i]);
	}
	for (;i<ctx->mangle_prefix;i++) {
		lead_chars[i] = '_';
	}

	/* the prefix is anything up to the first dot */
	if (dot_p) {
		prefix_len = PTR_DIFF(dot_p, name);
	} else {
		prefix_len = strlen(name);
	}

	/* the extension of the mangled name is taken from the first 3
	   ascii chars after the dot */
	extension_length = 0;
	if (dot_p) {
		for (i=1; extension_length < 3 && dot_p[i]; i++) {
			unsigned char c = dot_p[i];
			if (FLAG_CHECK(c, FLAG_ASCII)) {
				extension[extension_length++] = toupper(c);
			}
		}
	}
	   
	/* find the hash for this prefix */
	v = hash = mangle_hash(ctx, name, prefix_len);

	new_name = talloc_array(ctx, char, 13);
	if (new_name == NULL) {
		return NULL;
	}

	/* now form the mangled name. */
	for (i=0;i<ctx->mangle_prefix;i++) {
		new_name[i] = lead_chars[i];
	}
	new_name[7] = basechars[v % 36];
	new_name[6] = '~';	
	for (i=5; i>=ctx->mangle_prefix; i--) {
		v = v / 36;
		new_name[i] = basechars[v % 36];
	}

	/* add the extension */
	if (extension_length) {
		new_name[8] = '.';
		memcpy(&new_name[9], extension, extension_length);
		new_name[9+extension_length] = 0;
	} else {
		new_name[8] = 0;
	}

	if (cache83) {
		/* put it in the cache */
		cache_insert(ctx, name, prefix_len, hash);
	}

	M_DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n", 
		   name, hash, new_name, cache83));

	return new_name;
}
Beispiel #25
0
/*
  the main forward mapping function, which converts a long filename to 
  a 8.3 name

  if need83 is not set then we only do the mangling if the name is illegal
  as a long name

  if cache83 is not set then we don't cache the result

  the name parameter must be able to hold 13 bytes
*/
static void name_map(fstring name, BOOL need83, BOOL cache83, int default_case)
{
	char *dot_p;
	char lead_chars[7];
	char extension[4];
	unsigned int extension_length, i;
	unsigned int prefix_len;
	u32 hash, v;
	char new_name[13];

	/* reserved names are handled specially */
	if (!is_reserved_name(name)) {
		/* if the name is already a valid 8.3 name then we don't need to 
		   do anything */
		if (is_8_3(name, False, False)) {
			return;
		}

		/* if the caller doesn't strictly need 8.3 then just check for illegal 
		   filenames */
		if (!need83 && is_legal_name(name)) {
			return;
		}
	}

	/* find the '.' if any */
	dot_p = strrchr(name, '.');

	if (dot_p) {
		/* if the extension contains any illegal characters or
		   is too long or zero length then we treat it as part
		   of the prefix */
		for (i=0; i<4 && dot_p[i+1]; i++) {
			if (! FLAG_CHECK(dot_p[i+1], FLAG_ASCII)) {
				dot_p = NULL;
				break;
			}
		}
		if (i == 0 || i == 4) dot_p = NULL;
	}

	/* the leading characters in the mangled name is taken from
	   the first characters of the name, if they are ascii otherwise
	   '_' is used
	*/
	for (i=0;i<mangle_prefix && name[i];i++) {
		lead_chars[i] = name[i];
		if (! FLAG_CHECK(lead_chars[i], FLAG_ASCII)) {
			lead_chars[i] = '_';
		}
		lead_chars[i] = toupper(lead_chars[i]);
	}
	for (;i<mangle_prefix;i++) {
		lead_chars[i] = '_';
	}

	/* the prefix is anything up to the first dot */
	if (dot_p) {
		prefix_len = PTR_DIFF(dot_p, name);
	} else {
		prefix_len = strlen(name);
	}

	/* the extension of the mangled name is taken from the first 3
	   ascii chars after the dot */
	extension_length = 0;
	if (dot_p) {
		for (i=1; extension_length < 3 && dot_p[i]; i++) {
			char c = dot_p[i];
			if (FLAG_CHECK(c, FLAG_ASCII)) {
				extension[extension_length++] = toupper(c);
			}
		}
	}
	   
	/* find the hash for this prefix */
	v = hash = mangle_hash(name, prefix_len);

	/* now form the mangled name. */
	for (i=0;i<mangle_prefix;i++) {
		new_name[i] = lead_chars[i];
	}
	new_name[7] = base_forward(v % 36);
	new_name[6] = '~';	
	for (i=5; i>=mangle_prefix; i--) {
		v = v / 36;
		new_name[i] = base_forward(v % 36);
	}

	/* add the extension */
	if (extension_length) {
		new_name[8] = '.';
		memcpy(&new_name[9], extension, extension_length);
		new_name[9+extension_length] = 0;
	} else {
		new_name[8] = 0;
	}

	if (cache83) {
		/* put it in the cache */
		cache_insert(name, prefix_len, hash);
	}

	M_DEBUG(10,("name_map: %s -> %08X -> %s (cache=%d)\n", 
		   name, hash, new_name, cache83));

	/* and overwrite the old name */
	fstrcpy(name, new_name);

	/* all done, we've managed to mangle it */
}
Beispiel #26
0
static void server_recv_cb (EV_P_ ev_io *w, int revents)
{
    struct server_ctx *server_ctx = (struct server_ctx *)w;
    struct sockaddr src_addr;
    char *buf = malloc(BUF_SIZE);

    socklen_t addr_len = sizeof(src_addr);
    unsigned int offset = 0;

    ssize_t buf_len = recvfrom(server_ctx->fd, buf, BUF_SIZE, 0, &src_addr, &addr_len);

    if (buf_len == -1)
    {
        // error on recv
        // simply drop that packet
        if (verbose)
        {
            ERROR("udprelay_server_recvfrom");
        }
        goto CLEAN_UP;
    }

    if (verbose)
    {
        LOGD("[udp] server receive a packet.");
    }

#ifdef UDPRELAY_REMOTE
    buf = ss_decrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method);
#endif

#ifdef UDPRELAY_LOCAL
    uint8_t frag = *(uint8_t*)(buf + 2);
    offset += 3;
#endif

    /*
     *
     * SOCKS5 UDP Request
     * +----+------+------+----------+----------+----------+
     * |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
     * +----+------+------+----------+----------+----------+
     * | 2  |  1   |  1   | Variable |    2     | Variable |
     * +----+------+------+----------+----------+----------+
     *
     * SOCKS5 UDP Response
     * +----+------+------+----------+----------+----------+
     * |RSV | FRAG | ATYP | DST.ADDR | DST.PORT |   DATA   |
     * +----+------+------+----------+----------+----------+
     * | 2  |  1   |  1   | Variable |    2     | Variable |
     * +----+------+------+----------+----------+----------+
     *
     * shadowsocks UDP Request (before encrypted)
     * +------+----------+----------+----------+
     * | ATYP | DST.ADDR | DST.PORT |   DATA   |
     * +------+----------+----------+----------+
     * |  1   | Variable |    2     | Variable |
     * +------+----------+----------+----------+
     *
     * shadowsocks UDP Response (before encrypted)
     * +------+----------+----------+----------+
     * | ATYP | DST.ADDR | DST.PORT |   DATA   |
     * +------+----------+----------+----------+
     * |  1   | Variable |    2     | Variable |
     * +------+----------+----------+----------+
     *
     * shadowsocks UDP Request and Response (after encrypted)
     * +-------+--------------+
     * |   IV  |    PAYLOAD   |
     * +-------+--------------+
     * | Fixed |   Variable   |
     * +-------+--------------+
     *
     */

    char host[256] = {0};
    char port[64] = {0};

    int addr_header_len = parse_udprealy_header(buf + offset,
                          buf_len - offset, host, port);
    if (addr_header_len == 0)
    {
        // error in parse header
        goto CLEAN_UP;
    }
    char *addr_header = buf + offset;
    char *key = hash_key(addr_header, addr_header_len, &src_addr);
    struct cache *conn_cache = server_ctx->conn_cache;

    struct remote_ctx *remote_ctx = NULL;
    cache_lookup(conn_cache, key, (void*)&remote_ctx);

    if (remote_ctx == NULL)
    {
        if (verbose)
        {
            LOGD("[udp] cache missed: %s:%s", host, port);
        }
    }
    else
    {
        if (verbose)
        {
            LOGD("[udp] cache hit: %s:%s", host, port);
        }
    }

#ifdef UDPRELAY_LOCAL

    if (frag)
    {
        LOGE("drop a message since frag is not 0, but %d", frag);
        goto CLEAN_UP;
    }

    if (remote_ctx == NULL)
    {
        struct addrinfo hints;
        struct addrinfo *result;

        memset(&hints, 0, sizeof(struct addrinfo));
        hints.ai_family = AF_UNSPEC; /* Return IPv4 and IPv6 choices */
        hints.ai_socktype = SOCK_DGRAM; /* We want a UDP socket */

        int s = getaddrinfo(server_ctx->remote_host, server_ctx->remote_port,
                            &hints, &result);
        if (s != 0 || result == NULL)
        {
            LOGE("getaddrinfo: %s", gai_strerror(s));
            goto CLEAN_UP;
        }

        // Bind to any port
        int remotefd = create_remote_socket(result->ai_family == AF_INET6);
        if (remotefd < 0)
        {
            ERROR("udprelay bind() error..");
            // remember to free addrinfo
            freeaddrinfo(result);
            goto CLEAN_UP;
        }
        setnonblocking(remotefd);

#ifdef SO_NOSIGPIPE
        int opt = 1;
        setsockopt(remotefd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif
#ifdef SET_INTERFACE
        if (server_ctx->iface)
            setinterface(remotefd, server_ctx->iface);
#endif

        // Init remote_ctx
        remote_ctx = new_remote(remotefd, server_ctx);
        remote_ctx->src_addr = src_addr;
        remote_ctx->dst_addr = *result->ai_addr;
        remote_ctx->addr_header_len = addr_header_len;
        memcpy(remote_ctx->addr_header, addr_header, addr_header_len);

        // Add to conn cache
        cache_insert(conn_cache, key, (void *)remote_ctx);

        // Start remote io
        ev_io_start(EV_A_ &remote_ctx->io);

        // clean up
        freeaddrinfo(result);
    }

    buf_len -= offset;
    memmove(buf, buf + offset, buf_len);

    buf = ss_encrypt_all(BUF_SIZE, buf, &buf_len, server_ctx->method);

    int s = sendto(remote_ctx->fd, buf, buf_len, 0, &remote_ctx->dst_addr, sizeof(remote_ctx->dst_addr));

    if (s == -1)
    {
        ERROR("udprelay_sendto_remote");
    }

#else

    if (remote_ctx == NULL)
    {
        struct addrinfo hints;
        asyncns_query_t *query;
        memset(&hints, 0, sizeof(hints));
        hints.ai_family = AF_UNSPEC;
        hints.ai_socktype = SOCK_STREAM;

        query = asyncns_getaddrinfo(server_ctx->asyncns,
                                    host, port, &hints);

        if (query == NULL)
        {
            ERROR("udp_asyncns_getaddrinfo");
            goto CLEAN_UP;
        }

        struct query_ctx *query_ctx = new_query_ctx(query, buf + addr_header_len,
                buf_len - addr_header_len);
        query_ctx->server_ctx = server_ctx;
        query_ctx->addr_header_len = addr_header_len;
        query_ctx->src_addr = src_addr;
        memcpy(query_ctx->addr_header, addr_header, addr_header_len);

        ev_timer_start(EV_A_ &query_ctx->watcher);

    }
    else
    {

        int s = sendto(remote_ctx->fd, buf + addr_header_len,
                buf_len - addr_header_len, 0, &remote_ctx->dst_addr, sizeof(remote_ctx->dst_addr));

        if (s == -1)
        {
            ERROR("udprelay_sendto_remote");
        }

    }
#endif

CLEAN_UP:
    free(buf);

}
Beispiel #27
0
static void query_resolve_cb(EV_P_ ev_timer *watcher, int revents)
{
    int err;
    struct addrinfo *result, *rp;
    struct query_ctx *query_ctx = (struct query_ctx *)((void*)watcher);
    asyncns_t *asyncns = query_ctx->server_ctx->asyncns;
    asyncns_query_t *query = query_ctx->query;

    if (asyncns == NULL || query == NULL)
    {
        LOGE("invalid dns query.");
        close_and_free_query(EV_A_ query_ctx);
        return;
    }

    if (asyncns_wait(asyncns, 0) == -1)
    {
        // asyncns error
        FATAL("asyncns exit unexpectedly.");
    }

    if (!asyncns_isdone(asyncns, query))
    {
        // wait reolver
        return;
    }

    if (verbose)
    {
        LOGD("[udp] asyncns resolved.");
    }

    ev_timer_stop(EV_A_ watcher);

    err = asyncns_getaddrinfo_done(asyncns, query, &result);

    if (err)
    {
        ERROR("getaddrinfo");
    }
    else
    {
        // Use IPV4 address if possible
        for (rp = result; rp != NULL; rp = rp->ai_next)
        {
            if (rp->ai_family == AF_INET) break;
        }

        if (rp == NULL)
        {
            rp = result;
        }

        int remotefd = create_remote_socket(rp->ai_family == AF_INET6);
        if (remotefd != -1)
        {
            setnonblocking(remotefd);
#ifdef SO_NOSIGPIPE
            int opt = 1;
            setsockopt(remotefd, SOL_SOCKET, SO_NOSIGPIPE, &opt, sizeof(opt));
#endif
#ifdef SET_INTERFACE
            if (query_ctx->server_ctx->iface)
                setinterface(remotefd, query_ctx->server_ctx->iface);
#endif

            struct remote_ctx *remote_ctx = new_remote(remotefd, query_ctx->server_ctx);
            remote_ctx->src_addr = query_ctx->src_addr;
            remote_ctx->dst_addr = *rp->ai_addr;
            remote_ctx->server_ctx = query_ctx->server_ctx;
            remote_ctx->addr_header_len = query_ctx->addr_header_len;
            memcpy(remote_ctx->addr_header, query_ctx->addr_header, query_ctx->addr_header_len);

            // Add to conn cache
            char *key = hash_key(remote_ctx->addr_header,
                                 remote_ctx->addr_header_len, &remote_ctx->src_addr);
            cache_insert(query_ctx->server_ctx->conn_cache, key, (void *)remote_ctx);

            ev_io_start(EV_A_ &remote_ctx->io);

            int s = sendto(remote_ctx->fd, query_ctx->buf, query_ctx->buf_len, 0, &remote_ctx->dst_addr, sizeof(remote_ctx->dst_addr));

            if (s == -1)
            {
                ERROR("udprelay_sendto_remote");
                close_and_free_remote(EV_A_ remote_ctx);
            }

        }
        else
        {
            ERROR("udprelay bind() error..");
        }
    }

    // clean up
    asyncns_freeaddrinfo(result);
    close_and_free_query(EV_A_ query_ctx);
}
Beispiel #28
0
static rlm_rcode_t mod_cache_it(void *instance, UNUSED void *thread, REQUEST *request)
{
	rlm_cache_entry_t	*c = NULL;
	rlm_cache_t const	*inst = instance;

	rlm_cache_handle_t	*handle;

	fr_cursor_t		cursor;
	VALUE_PAIR		*vp;

	bool			merge = true, insert = true, expire = false, set_ttl = false;
	int			exists = -1;

	uint8_t			buffer[1024];
	uint8_t const		*key;
	ssize_t			key_len;
	rlm_rcode_t		rcode = RLM_MODULE_NOOP;

	int			ttl = inst->config.ttl;

	key_len = tmpl_expand((char const **)&key, (char *)buffer, sizeof(buffer),
			      request, inst->config.key, NULL, NULL);
	if (key_len < 0) return RLM_MODULE_FAIL;

	if (key_len == 0) {
		REDEBUG("Zero length key string is invalid");
		return RLM_MODULE_INVALID;
	}

	/*
	 *	If Cache-Status-Only == yes, only return whether we found a
	 *	valid cache entry
	 */
	vp = fr_pair_find_by_da(request->control, attr_cache_status_only, TAG_ANY);
	if (vp && vp->vp_bool) {
		RINDENT();
		RDEBUG3("status-only: yes");
		REXDENT();

		if (cache_acquire(&handle, inst, request) < 0) return RLM_MODULE_FAIL;

		rcode = cache_find(&c, inst, request, &handle, key, key_len);
		if (rcode == RLM_MODULE_FAIL) goto finish;
		rad_assert(!inst->driver->acquire || handle);

		rcode = c ? RLM_MODULE_OK:
			    RLM_MODULE_NOTFOUND;
		goto finish;
	}

	/*
	 *	Figure out what operation we're doing
	 */
	vp = fr_pair_find_by_da(request->control, attr_cache_allow_merge, TAG_ANY);
	if (vp) merge = vp->vp_bool;

	vp = fr_pair_find_by_da(request->control, attr_cache_allow_insert, TAG_ANY);
	if (vp) insert = vp->vp_bool;

	vp = fr_pair_find_by_da(request->control, attr_cache_ttl, TAG_ANY);
	if (vp) {
		if (vp->vp_int32 == 0) {
			expire = true;
		} else if (vp->vp_int32 < 0) {
			expire = true;
			ttl = -(vp->vp_int32);
		/* Updating the TTL */
		} else {
			set_ttl = true;
			ttl = vp->vp_int32;
		}
	}

	RINDENT();
	RDEBUG3("merge  : %s", merge ? "yes" : "no");
	RDEBUG3("insert : %s", insert ? "yes" : "no");
	RDEBUG3("expire : %s", expire ? "yes" : "no");
	RDEBUG3("ttl    : %i", ttl);
	REXDENT();
	if (cache_acquire(&handle, inst, request) < 0) return RLM_MODULE_FAIL;

	/*
	 *	Retrieve the cache entry and merge it with the current request
	 *	recording whether the entry existed.
	 */
	if (merge) {
		rcode = cache_find(&c, inst, request, &handle, key, key_len);
		switch (rcode) {
		case RLM_MODULE_FAIL:
			goto finish;

		case RLM_MODULE_OK:
			rcode = cache_merge(inst, request, c);
			exists = 1;
			break;

		case RLM_MODULE_NOTFOUND:
			rcode = RLM_MODULE_NOTFOUND;
			exists = 0;
			break;

		default:
			rad_assert(0);
		}
		rad_assert(!inst->driver->acquire || handle);
	}

	/*
	 *	Expire the entry if told to, and we either don't know whether
	 *	it exists, or we know it does.
	 *
	 *	We only expire if we're not inserting, as driver insert methods
	 *	should perform upserts.
	 */
	if (expire && ((exists == -1) || (exists == 1))) {
		if (!insert) {
			rad_assert(!set_ttl);
			switch (cache_expire(inst, request, &handle, key, key_len)) {
			case RLM_MODULE_FAIL:
				rcode = RLM_MODULE_FAIL;
				goto finish;

			case RLM_MODULE_OK:
				if (rcode == RLM_MODULE_NOOP) rcode = RLM_MODULE_OK;
				break;

			case RLM_MODULE_NOTFOUND:
				if (rcode == RLM_MODULE_NOOP) rcode = RLM_MODULE_NOTFOUND;
				break;

			default:
				rad_assert(0);
				break;
			}
			/* If it previously existed, it doesn't now */
		}
		/* Otherwise use insert to overwrite */
		exists = 0;
	}

	/*
	 *	If we still don't know whether it exists or not
	 *	and we need to do an insert or set_ttl operation
	 *	determine that now.
	 */
	if ((exists < 0) && (insert || set_ttl)) {
		switch (cache_find(&c, inst, request, &handle, key, key_len)) {
		case RLM_MODULE_FAIL:
			rcode = RLM_MODULE_FAIL;
			goto finish;

		case RLM_MODULE_OK:
			exists = 1;
			if (rcode != RLM_MODULE_UPDATED) rcode = RLM_MODULE_OK;
			break;

		case RLM_MODULE_NOTFOUND:
			exists = 0;
			break;

		default:
			rad_assert(0);
		}
		rad_assert(!inst->driver->acquire || handle);
	}

	/*
	 *	We can only alter the TTL on an entry if it exists.
	 */
	if (set_ttl && (exists == 1)) {
		rad_assert(c);

		c->expires = request->packet->timestamp.tv_sec + ttl;

		switch (cache_set_ttl(inst, request, &handle, c)) {
		case RLM_MODULE_FAIL:
			rcode = RLM_MODULE_FAIL;
			goto finish;

		case RLM_MODULE_NOTFOUND:
		case RLM_MODULE_OK:
			if (rcode != RLM_MODULE_UPDATED) rcode = RLM_MODULE_OK;
			goto finish;

		default:
			rad_assert(0);
		}
	}

	/*
	 *	Inserts are upserts, so we don't care about the
	 *	entry state, just that we're not meant to be
	 *	setting the TTL, which precludes performing an
	 *	insert.
	 */
	if (insert && (exists == 0)) {
		switch (cache_insert(inst, request, &handle, key, key_len, ttl)) {
		case RLM_MODULE_FAIL:
			rcode = RLM_MODULE_FAIL;
			goto finish;

		case RLM_MODULE_OK:
			if (rcode != RLM_MODULE_UPDATED) rcode = RLM_MODULE_OK;
			break;

		case RLM_MODULE_UPDATED:
			rcode = RLM_MODULE_UPDATED;
			break;

		default:
			rad_assert(0);
		}
		rad_assert(!inst->driver->acquire || handle);
		goto finish;
	}


finish:
	cache_free(inst, &c);
	cache_release(inst, request, &handle);

	/*
	 *	Clear control attributes
	 */
	for (vp = fr_cursor_init(&cursor, &request->control);
	     vp;
	     vp = fr_cursor_next(&cursor)) {
	     again:
		if (!fr_dict_attr_is_top_level(vp->da)) continue;

		switch (vp->da->attr) {
		case FR_CACHE_TTL:
		case FR_CACHE_STATUS_ONLY:
		case FR_CACHE_ALLOW_MERGE:
		case FR_CACHE_ALLOW_INSERT:
		case FR_CACHE_MERGE_NEW:
			RDEBUG2("Removing &control:%s", vp->da->name);
			vp = fr_cursor_remove(&cursor);
			talloc_free(vp);
			vp = fr_cursor_current(&cursor);
			if (!vp) break;
			goto again;
		}
	}

	return rcode;
}
Beispiel #29
0
Dir*
cache_lookup     (Cache        *cache,
                  const gchar  *key,
                  gboolean create_if_missing,
                  GError  **err)
{
  Dir* dir;
  
  g_assert(key != NULL);
  g_return_val_if_fail(cache != NULL, NULL);
  
  /* Check cache */
  dir = g_hash_table_lookup(cache->cache, key);
  
  if (dir != NULL)
    {
      gconf_log(GCL_DEBUG, "Using dir %s from cache", key);
      return dir;
    }
  else
    {
      /* Not in cache, check whether we already failed
         to load it */
      if (cache_is_nonexistent(cache, key))
        {
          if (!create_if_missing)
            return NULL;
        }
      else
        {
          /* Didn't already fail to load, try to load */
          dir = dir_load (key, cache->root_dir, err);
          
          if (dir != NULL)
            {
              g_assert(err == NULL || *err == NULL);
              
              /* Cache it and add to parent */
              cache_insert (cache, dir);
              cache_add_to_parent (cache, dir);
              
              return dir;
            }
          else
            {
              /* Remember that we failed to load it */
              if (!create_if_missing)
                {
                  cache_set_nonexistent(cache, key, TRUE);
              
                  return NULL;
                }
              else
                {
                  if (err && *err)
                    {
                      g_error_free(*err);
                      *err = NULL;
                    }
                }
            }
        }
    }
  
  g_assert(dir == NULL);
  g_assert(create_if_missing);
  g_assert(err == NULL || *err == NULL);
  
  if (dir == NULL)
    {
      gconf_log(GCL_DEBUG, "Creating new dir %s", key);
      
      dir = dir_new(key, cache->root_dir, cache->dir_mode, cache->file_mode);

      if (!dir_ensure_exists(dir, err))
        {
          dir_destroy(dir);
          
          g_return_val_if_fail((err == NULL) ||
                               (*err != NULL) ,
                               NULL);
          return NULL;
        }
      else
        {
          cache_insert (cache, dir);
          cache_add_to_parent (cache, dir);
          cache_unset_nonexistent (cache, dir_get_name (dir));
        }
    }

  return dir;
}
Beispiel #30
0
// NEW-LAB2 
void dcache_insert(ADDRINT addr)  // NEW-LAB2 
{                                 // NEW-LAB2 
  /* dcache insert function */   // NEW-LAB2 
  cache_insert(data_cache, addr) ;   // NEW-LAB2 
 
}   // NEW-LAB2