Ejemplo n.º 1
0
/**
 * free_devtable_info - free device table information.
 *
 * This function frees the path hash table and the name hash tables.
 */
void free_devtable_info(void)
{
	struct hashtable_itr *ph_itr;
	struct path_htbl_element *ph_elt;

	if (!path_htbl)
		return;

	if (hashtable_count(path_htbl) > 0) {
		ph_itr = hashtable_iterator(path_htbl);
		do {
			ph_elt = hashtable_iterator_value(ph_itr);
			/*
			 * Note, since we use the same string for the key and
			 * @name in the name hash table elements, we do not
			 * have to iterate name hash table because @name memory
			 * will be freed when freeing the key.
			 */
			hashtable_destroy(ph_elt->name_htbl, 1);
		} while (hashtable_iterator_advance(ph_itr));
	}
	hashtable_destroy(path_htbl, 1);
}
Ejemplo n.º 2
0
/* check if a sender has not sent info to us for an extended period
 * of time.
 */
void
checkGoneAwaySenders(const time_t tCurr)
{
	struct hashtable_itr *itr = NULL;
	struct sender_stats *stat;
	const time_t rqdLast = tCurr - glblSenderStatsTimeout;
	struct tm tm;

	pthread_mutex_lock(&mutSenders);

	/* Iterator constructor only returns a valid iterator if
	 * the hashtable is not empty
	 */
	if(hashtable_count(stats_senders) > 0) {
		itr = hashtable_iterator(stats_senders);
		do {
			stat = (struct sender_stats*)hashtable_iterator_value(itr);
			if(stat->lastSeen < rqdLast) {
				if(glblReportGoneAwaySenders) {
					localtime_r(&stat->lastSeen, &tm);
					LogMsg(0, RS_RET_SENDER_GONE_AWAY,
						LOG_WARNING,
						"removing sender '%s' from connection "
						"table, last seen at "
						"%4.4d-%2.2d-%2.2d %2.2d:%2.2d:%2.2d",
						stat->sender,
						tm.tm_year+1900, tm.tm_mon+1, tm.tm_mday,
						tm.tm_hour, tm.tm_min, tm.tm_sec);
				}
				hashtable_remove(stats_senders, (void*)stat->sender);
			}
		} while (hashtable_iterator_advance(itr));
	}

	pthread_mutex_unlock(&mutSenders);
	free(itr);
}
Ejemplo n.º 3
0
void *
cache_free(cache_t *c)
{

    	cache_value_t *v;

    struct hashtable_itr *itr;
    if (hashtable_count(c->c_data) > 0)
    {
        itr = hashtable_iterator(c->c_data);
        do {
            v = hashtable_iterator_value(itr);

	    c->c_freevalue(v->p);
	    free(v);
        } while (hashtable_iterator_advance(itr));

     	free(itr);

    }

    hashtable_destroy(c->c_data,0); /* second arg indicates "free(value)" */

}
Ejemplo n.º 4
0
void
print_distinct(int cutoff)
{
	struct hashtable *hash;
	DBC *dbcp;
	DBT key, data;
	int ret;

	//create_hashtable(1, hashfromkey_url, equalkeys_url);


	memset(&key, 0, sizeof(key));
	memset(&data, 0, sizeof(data));

	/* Acquire a cursor for the database. */
	if ((ret = maindb->cursor(maindb, NULL, &dbcp, 0)) != 0) {
		maindb->err(maindb, ret, "DB->cursor");
		exit(1);
	}

	/* Walk through the database and print out the key/data pairs. */
	while ((ret = dbcp->c_get(dbcp, &key, &data, DB_NEXT)) == 0) {
		struct in_addr in;
		struct dbkey dbkey;
		struct dbkey dbkey2;
		struct dbkey dbkey3;
		unsigned int num;
		unsigned int i;
		char *url;
		DBT key2, data2;
		DBT key3, data3;
		char url2[10240];

		num = *(unsigned int *)data.data;
		memcpy(&dbkey, key.data, key.size);

		if (dbkey.num != 0)
			continue;
		in.s_addr = dbkey.addr;

		if (num < cutoff)
			continue;
		printf("Got %d record for %s\n", num, inet_ntoa(in));
#if 0
		hash = create_hashtable(10, hashfromkey_url, equalkeys_url);
		for (i = 1; i <= num; i++) {
			char *hashkey;
			dbkey2.addr = in.s_addr;
			if (num > 1)
				dbkey2.num = 2;
			else
				dbkey2.num = i;

			memset(&key2, 0, sizeof(key2));
			key2.data = &dbkey2;
			key2.size = sizeof(dbkey2);
			memset(&data2, 0, sizeof(data2));
			//data2.data = url2;
			//data2.size = sizeof(url2);

			if ((ret = maindb->get(maindb, NULL, &key2, &data2, 0) != 0)) {
				maindb->err(maindb, ret, "DBcursor->get");
				exit(1);
			}

			strncpy(url2, data2.data, data2.size);
			url2[data2.size] = '\0';
			//printf("\tFound: %d\n", data2.size);
			//printf("\tFound: %s\n", url2);

			hashkey = strdup(url2);
			if (hashkey == NULL)
				err(1, "Oops, hashkey is null");
			if (!hashtable_search(hash, url2)) {
				hashkey = strdup(url2);
				if (hashkey == NULL)
					err(1, "Oops, hashkey is null");

				hashtable_insert(hash, hashkey, &fakeval);
			}

		}
		if (num != hashtable_count(hash) && hashtable_count(hash) != 1) {
			printf("%d is really %d\n", num, hashtable_count(hash));
		}
		hashtable_destroy(hash, 0);
#endif
	}
	if (ret != DB_NOTFOUND) {
		maindb->err(maindb, ret, "DBcursor->c_get");
		exit(1);
	}

	if ((ret = dbcp->c_close(dbcp)) != 0)
		maindb->err(maindb, ret, "DBcursor->close");

}
Ejemplo n.º 5
0
static void dump_qstats_to_db(void) {
    /* qstats hashtable */
    char *kk;
    qstats_t *s;
    struct hashtable *qstats_htp = NULL;    
    qstats_htp = create_hashtable(64, hashfromkey, equalkeys);
    assert(qstats_htp != NULL);
    
    /* cp hashtable to stats table, this is very fast in-memory */
    pthread_rwlock_rdlock(&qlist_ht_lock);
    char *k;
    queue_t *q;
    int result;
    struct hashtable_itr *itr = NULL;
    itr = hashtable_iterator(qlist_htp);
    assert(itr != NULL);
    if (hashtable_count(qlist_htp) > 0)
    {
        do {
            k = hashtable_iterator_key(itr);
            q = hashtable_iterator_value(itr);
            pthread_mutex_lock(&(q->lock));
            if (q->old_set_hits == q->set_hits &&
                q->old_get_hits == q->get_hits) {
                pthread_mutex_unlock(&(q->lock));
                continue;
            }
            q->old_set_hits = q->set_hits;
            q->old_get_hits = q->get_hits;
            pthread_mutex_unlock(&(q->lock));
            kk = strdup(k);
            assert(kk);
            s = calloc(1, sizeof(qstats_t));
            assert(s);
            s->set_hits = q->old_set_hits;
            s->get_hits = q->old_get_hits;
            result = hashtable_insert(qstats_htp, (void *)kk, (void *)s);
            assert(result != 0);
        } while (hashtable_iterator_advance(itr));
    }
    free(itr);
    itr = NULL;
    pthread_rwlock_unlock(&qlist_ht_lock);
    
    /* dump stats hashtable to db */
    DBT dbkey, dbdata;
    int ret;
    DB_TXN *txnp = NULL;
    ret = envp->txn_begin(envp, NULL, &txnp, 0);
    CHECK_DB_RET(ret);
    itr = hashtable_iterator(qstats_htp);
    assert(itr != NULL);
    if (hashtable_count(qstats_htp) > 0)
    {
        do {
            kk = hashtable_iterator_key(itr);
            s = hashtable_iterator_value(itr);
            BDB_CLEANUP_DBT();
            dbkey.data = (void *)kk;
            dbkey.size = strlen(kk) + 1;
            dbdata.data = (void *)s;
            dbdata.size = sizeof(qstats_t);
            ret = qlist_dbp->put(qlist_dbp, txnp, &dbkey, &dbdata, 0);
            CHECK_DB_RET(ret);
            fprintf(stderr, "dump stats[%s], set_hits: %lld, get_hits: %lld \n",
                    kk, s->set_hits, s->get_hits);
        } while (hashtable_iterator_advance(itr));
    }
    free(itr);
    itr = NULL;
    ret = txnp->commit(txnp, 0);
    CHECK_DB_RET(ret);

    hashtable_destroy(qstats_htp, 1);
    qstats_htp = NULL;
    return;
dberr:
    if(itr != NULL) {
        free(itr);
    }
    if (qstats_htp != NULL) {
        hashtable_destroy(qstats_htp, 1);
    }
    if (txnp != NULL){
        txnp->abort(txnp);
    }
    if (settings.verbose > 1) {
        fprintf(stderr, "dump_qstats_to_db: %s\n", db_strerror(ret));
    }
}
Ejemplo n.º 6
0
int bbdocument_add(char subname[],char documenturi[],char documenttype[],char document[],const int dokument_size,unsigned int lastmodified,char *acl_allow, char *acl_denied,const char title[], char doctype[], char *attributes, container *attrkeys) {

	struct ReposetoryHeaderFormat ReposetoryHeader;

	int htmlbuffersize = 0;//((dokument_size *2) +512);	//+512 da vi skal ha med div meta data, som html kode
	char *htmlbuffer = NULL;// = malloc(htmlbuffersize);
	char *imagebuffer;
	char *documenttype_real;
	size_t imageSize;
	unsigned int DocIDForExistTest;
	unsigned int lastmodifiedForExistTest;
	struct hashtable *metahash = NULL;
	buffer *documentbuffer;

	memset(&ReposetoryHeader,0,sizeof(ReposetoryHeader));

	printf("bbdocument_add: \"%s\"\n",documenturi);

	printf("bbdocument_add: Attributes = \"%s\" (", attributes);
	if (attrkeys!=NULL) printf("+)\n");
	else printf(" )\n");


	//tester at det ikke finnes først. Hvis det finnes hånterer vi det. Eventuelt også lagre  den nye versjonen hvis det er forandret.
	if (uriindex_get(documenturi,&DocIDForExistTest,&lastmodifiedForExistTest,subname)) {

		if (lastmodifiedForExistTest == lastmodified) {
			printf("bbdocument_add: Uri \"%s\" all redy exist with DocID \"%u\" and time \"%u\"\n",documenturi,DocIDForExistTest,lastmodifiedForExistTest);
			return 1;
		}
		//hvis url er kjent, men oppdater rebruker vi den.
		ReposetoryHeader.DocID = DocIDForExistTest;
	}
	else {
		//hvis vi ikke har DocID har vi et system som trenger å få opprettet det. For eks bb eller bdisk.
		ReposetoryHeader.DocID = rGeneraeADocID(subname);

		#ifdef DEBUG
			printf("Dident have a known DocID for document. Did generet on. DOcID is now %u\n",ReposetoryHeader.DocID);
		#endif

	}

	// hvis vi har en "text applicatino" enkoding, som ikke er en vanlig tekst fil, men tekst som kommer fra 
	// en apllikasjon behandler vi det som text.
	//if (strcmp(documenttype,"tapp") == 0) {
	//	documenttype_real = strdup("text");
	//}
	//else 
	if (documenttype[0] == '\0') {
		if ((documenttype_real = sfindductype(documenturi)) == NULL) {
			printf("Will use .none as documenttype because I can't decide format. File name isent dos type (8.3): %s\n", documenturi);
			documenttype_real = strdup("none");
			
		}
	}
	else {
		documenttype_real = malloc(strlen(documenttype)+1);
		strcpy(documenttype_real,documenttype);
	}



	//hvis vi ikke her med noen egen doctype så bruker vi den vi har fått via documenttype
	if (doctype[0] == '\0') {
		//vi trenger ikke å ha \0 på slutten her
		strncpy(ReposetoryHeader.doctype,documenttype_real,sizeof(ReposetoryHeader.doctype));
	}
	else {
		//vi trenger ikke å ha \0 på slutten her
		strncpy(ReposetoryHeader.doctype,doctype,sizeof(ReposetoryHeader.doctype));
	}

	documentbuffer = buffer_init(0);
	if (!bbdocument_convert(documenttype_real,document,dokument_size,documentbuffer,title,subname,documenturi, lastmodified,acl_allow, acl_denied, &metahash)) {

		printf("can't run bbdocument_convert\n");
		//lager en tom html buffer
		//Setter titelen som subjekt. Hva hvis vi ikke har title?
		htmlbuffersize = strlen(html_text_tempelate) + strlen(title) + 1;
		htmlbuffer = malloc(htmlbuffersize);
		snprintf(htmlbuffer, htmlbuffersize, html_text_tempelate,title,"");
		htmlbuffersize = strlen(htmlbuffer);
		printf("useing title \"%s\" as title\n",title);
		printf("htmlbuffersize %i\n",htmlbuffersize);
		free(buffer_abort(documentbuffer));
	} else {
		htmlbuffersize = buffer_length(documentbuffer);
		htmlbuffer = buffer_exit(documentbuffer);
	}

	buffer *attrbuffer = buffer_init(-1);
	bprintf(attrbuffer, "%s,", attributes);

	if (metahash) {
		struct hashtable_itr *itr;

		if (hashtable_count(metahash) > 0) {
			itr = hashtable_iterator(metahash);
			do {
				char *key, *value;

				key = hashtable_iterator_key(itr);
				value = hashtable_iterator_value(itr);

				printf("%s: Key: %s Value: %s\n", documenttype_real, key, value);

				if (strcmp(key, "lastmodified") == 0) {
					lastmodified = atol(value);
					continue;
				}

				bprintf(attrbuffer, "%s=%s,", key, value);
			} while (hashtable_iterator_advance(itr));

			free(itr);
		}
		hashtable_destroy(metahash, 1);
	}
	char *all_attributes = buffer_exit(attrbuffer);



	//prøver å lag et bilde
	//if ( (imagebuffer = generate_thumbnail( document, dokument_size, &imageSize )) == NULL ) {
	if (!bbdocument_makethumb(documenttype_real,document,dokument_size,&imagebuffer,&imageSize)) {
		printf("can't generate image\n");
		ReposetoryHeader.imageSize = 0;
		imagebuffer = NULL;
	}
	else {
		debug("generated image\n");
		ReposetoryHeader.imageSize = imageSize;
	}


	ReposetoryHeader.clientVersion = 2.14;

	//runarb:  8 juli 2008: tar bort bruken av ReposetoryHeader's url
	//runarb: 11 juli 2008: kan ikke gjøre dette, da vi kopierer den inn i DocumentIndex fra ReposetoryHeader 
	strncpy(ReposetoryHeader.url,documenturi,sizeof(ReposetoryHeader.url));
		

	ReposetoryHeader.response = 200;
	strcpy(ReposetoryHeader.content_type,"htm");

	ReposetoryHeader.acl_allowSize = strlen(acl_allow);
#ifdef IIACL
	ReposetoryHeader.acl_deniedSize = strlen(acl_denied);
#endif
	ReposetoryHeader.time = lastmodified;

	ReposetoryHeader.storageTime = 0; //setes automatisk av rApendPostcompress

#ifdef DEBUG
	printf("ACL was allow \"%s\", %i bytes, denied \"%s\", %i bytes\nsubname %s\n",acl_allow,ReposetoryHeader.acl_allowSize,acl_allow,ReposetoryHeader.acl_allowSize,subname);
#endif

	ReposetoryHeader.urllen = strlen(documenturi);
	ReposetoryHeader.attributeslen = strlen(all_attributes);
	rApendPostcompress(&ReposetoryHeader, htmlbuffer, imagebuffer, subname, acl_allow, acl_denied, NULL, documenturi, all_attributes, attrkeys, htmlbuffersize);

#ifdef DEBUG	
	printf("legger til DocID \"%u\", time \"%u\"\n",ReposetoryHeader.DocID,lastmodified);
	printf("htmlSize %u, imageSize %ho\n",ReposetoryHeader.htmlSize2,ReposetoryHeader.imageSize);
	printf("html: -%s-\n",htmlbuffer);
#endif

	uriindex_add(documenturi,ReposetoryHeader.DocID,lastmodified,subname);

	free(all_attributes);
	free(htmlbuffer);
	free(documenttype_real);

	if (imagebuffer != NULL) {
		free(imagebuffer);
	}

	return 1;
}	
Ejemplo n.º 7
0
void transaction_clear_readset(transaction* t) {
	if (hashtable_count(t->rs) > 0) {
    	hashtable_destroy(t->rs, 1);
		t->rs = create_hashtable(hashtable_init);
	}
}
Ejemplo n.º 8
0
int transaction_serialize(transaction* t, tr_submit_msg* msg, int max_size) {
    int size = 0;
    int hsize = 0;
	key* k;
    flat_key_val* kv;
    flat_key_hash* kh;
	struct hashtable_itr* itr;
	
	msg->type = TRANSACTION_SUBMIT;
    msg->id.client_id = t->id.client_id;
    msg->id.seqnumber = t->id.seqnumber;
    msg->id.node_id = NodeID;
    msg->start = t->st;
    msg->readset_count = 0;
    msg->writeset_count = 0;
    
    // copy readset hashes
	if (hashtable_count(t->rs) > 0) {
		itr = hashtable_iterator(t->rs);
		do {
			if ((size + (int)sizeof(flat_key_hash)) > max_size) {
				return -1;
			}
				
			k = hashtable_iterator_key(itr);
			kh = (flat_key_hash*)&msg->data[size];
			
			kh->hash[0] = hashtable_iterator_hash(itr);
			kh->hash[1] = djb2_hash(k->data, k->size);
			
			size += sizeof(flat_key_hash);
			msg->readset_count++;
		} while (hashtable_iterator_advance(itr));
		free(itr);
	}

    
    // copy writeset hashes
	if (hashtable_count(t->ws) > 0) {
		itr = hashtable_iterator(t->ws);
		do {
			if ((size + (int)sizeof(flat_key_hash)) > max_size) {
				return -1;
			}
			
			k = hashtable_iterator_key(itr);
			kh = (flat_key_hash*)&msg->data[size];
			
			kh->hash[0] = hashtable_iterator_hash(itr);
			kh->hash[1] = djb2_hash(k->data, k->size);
			
			size += sizeof(flat_key_hash);
			msg->writeset_count++;
		} while (hashtable_iterator_advance(itr));
		free(itr);
		hsize = size;
		
		itr = hashtable_iterator(t->ws);
		do {
			kv = hashtable_iterator_value(itr);
			if ((size + (int)FLAT_KEY_VAL_SIZE(kv)) > max_size) {
				return -1;
			}
			
			memcpy(&msg->data[size], kv, FLAT_KEY_VAL_SIZE(kv));
			size += (int)FLAT_KEY_VAL_SIZE(kv);
		} while (hashtable_iterator_advance(itr));
		free(itr);
	}
    msg->writeset_size = (size - hsize);
    return TR_SUBMIT_MSG_SIZE(msg);
}
Ejemplo n.º 9
0
int transaction_read_only(transaction* t) {
    return (hashtable_count(t->ws) == 0);
}
Ejemplo n.º 10
0
TPM_RESULT VTPM_SaveManagerData(void) {
  TPM_RESULT status=TPM_SUCCESS;
  int fh, dmis=-1;

  BYTE *flat_boot_key=NULL, *flat_dmis=NULL, *flat_enc=NULL;
  buffer_t clear_flat_global=NULL_BUF, enc_flat_global=NULL_BUF;
  UINT32 storageKeySize = buffer_len(&vtpm_globals->storageKeyWrap);
  UINT32 bootKeySize = buffer_len(&vtpm_globals->bootKeyWrap);
  struct pack_buf_t storage_key_pack = {storageKeySize, vtpm_globals->storageKeyWrap.bytes};
  struct pack_buf_t boot_key_pack = {bootKeySize, vtpm_globals->bootKeyWrap.bytes};
  BYTE vtpm_manager_gen = VTPM_MANAGER_GEN;

  struct hashtable_itr *dmi_itr;
  VTPM_DMI_RESOURCE *dmi_res;

  UINT32 boot_key_size = 0, flat_dmis_size = 0;

  // Initially fill these with buffer sizes for each data type. Later fill
  // in actual size, once flattened.
  boot_key_size =  sizeof(UINT32) +       // bootkeysize
                   bootKeySize;           // boot key

  TPMTRYRETURN(buffer_init(&clear_flat_global,sizeof(BYTE) + // manager version
                                              3*sizeof(TPM_DIGEST) + // Auths
                                              sizeof(UINT32) +// storagekeysize
                                              storageKeySize, NULL) ); // storage key


  flat_boot_key = (BYTE *) malloc( boot_key_size );
  flat_enc = (BYTE *) malloc( sizeof(UINT32) );

  boot_key_size = BSG_PackList(flat_boot_key, 1,
                               BSG_TPM_SIZE32_DATA, &boot_key_pack);

  BSG_PackList(clear_flat_global.bytes, 4,
                BSG_TYPE_BYTE,    &vtpm_manager_gen,
                BSG_TPM_AUTHDATA, &vtpm_globals->owner_usage_auth,
                BSG_TPM_SECRET,   &vtpm_globals->storage_key_usage_auth,
                BSG_TPM_SIZE32_DATA, &storage_key_pack);

  TPMTRYRETURN(envelope_encrypt(&clear_flat_global,
                                &vtpm_globals->bootKey,
                                &enc_flat_global) );

  BSG_PackConst(buffer_len(&enc_flat_global), 4, flat_enc);

  // Per DMI values to be saved (if any exit)
  if (hashtable_count(vtpm_globals->dmi_map) > 1) {

    flat_dmis = (BYTE *) malloc( 
                     (hashtable_count(vtpm_globals->dmi_map) - 1) * // num DMIS (-1 for Dom0)
                     (sizeof(UINT32) +sizeof(BYTE) + 2*sizeof(TPM_DIGEST)) ); // Per DMI info

    dmi_itr = hashtable_iterator(vtpm_globals->dmi_map);
    do {
      dmi_res = (VTPM_DMI_RESOURCE *) hashtable_iterator_value(dmi_itr);
      dmis++;

      // No need to save dmi0.
      if (dmi_res->dmi_id == 0)
        continue;


      flat_dmis_size += BSG_PackList( flat_dmis + flat_dmis_size, 4,
                                        BSG_TYPE_UINT32, &dmi_res->dmi_id,
                                        BSG_TYPE_BYTE, &dmi_res->dmi_type,
                                        BSG_TPM_DIGEST, &dmi_res->NVM_measurement,
                                        BSG_TPM_DIGEST, &dmi_res->DMI_measurement);

    } while (hashtable_iterator_advance(dmi_itr));
  }

  fh = open(STATE_FILE, O_WRONLY | O_CREAT, S_IREAD | S_IWRITE);
  if (fh == -1) {
    vtpmlogerror(VTPM_LOG_VTPM, "Unable to open %s file for write.\n", STATE_FILE);
    status = TPM_IOERROR;
    goto abort_egress;
  }

  if ( ( write(fh, flat_boot_key, boot_key_size) != boot_key_size ) ||
       ( write(fh, flat_enc, sizeof(UINT32)) != sizeof(UINT32) ) ||
       ( write(fh, enc_flat_global.bytes, buffer_len(&enc_flat_global)) != buffer_len(&enc_flat_global) ) ||
       ( write(fh, flat_dmis, flat_dmis_size) != flat_dmis_size ) ) {
    vtpmlogerror(VTPM_LOG_VTPM, "Failed to completely write service data.\n");
    status = TPM_IOERROR;
    goto abort_egress;
 }

  goto egress;

 abort_egress:
 egress:

  free(flat_boot_key);
  free(flat_enc);
  buffer_free(&enc_flat_global);
  free(flat_dmis);
  close(fh);

  vtpmloginfo(VTPM_LOG_VTPM, "Saved VTPM Manager state (status = %d, dmis = %d)\n", (int) status, dmis);
  return status;
}
Ejemplo n.º 11
0
//GRAPH FUNCTIONS

Graph*
gNew() {
  Graph *this = (Graph*)malloc(sizeof(Graph));
  this->vertices = create_hashtable_string(16); //TODO: find a better number.

  return this;
}

void
gDestroyBasic( Graph* this, int free_edge_payloads ) {

  //destroy each vertex contained within
  struct hashtable_itr *itr = hashtable_iterator(this->vertices);
  int next_exists = hashtable_count(this->vertices);

  while(itr && next_exists) {
    Vertex* vtx = hashtable_iterator_value( itr );
    vDestroy( vtx, 1 );
    next_exists = hashtable_iterator_advance( itr );
  }

  free(itr);
  //destroy the table
  hashtable_destroy( this->vertices, 0 );
  //destroy the graph object itself
  free( this );

}
Ejemplo n.º 12
0
static void doPacketChunking(u_char* data, int skblen)
{
	if (skblen >= MAX_PKT_SIZE) {
		fprintf(stderr, "skip too large packet: %d bytes\n", skblen);
		exit(0);
	}

	if (skblen < g_WindowSize) {
		if (g_Verbose) {
			fprintf(stderr, "skip too small packet: %d bytes\n",
					skblen);
		}
		return;
	}

	#if 0
	fprintf(stderr, "### get %d bytes packet\n", skblen);
	#endif

	/* first check if we have to evict an old packet */
	unsigned int numBoundaries = 0;
	RabinBoundary* rbdrs = NULL;
	int i;
	int nextId = (g_CurPacketId + 1) % g_MaxPackets;
	if (g_PacketCache[nextId].length > 0) {
		/* valid entry: release its fingerprints */
		rbdrs = doRabin((u_char*)g_PacketCache[nextId].data,
				g_PacketCache[nextId].length, &numBoundaries);
		for (i = 0; i < numBoundaries; i++) {
			/* release finger index */
			FingerEntry* fe_val = hashtable_search(g_FingerTable,
					&rbdrs[i].finger);
			if (fe_val != NULL && fe_val->pktId == nextId) {
				fe_val = hashtable_remove(g_FingerTable,
						&rbdrs[i].finger);
				free(fe_val);
			}
		}

		/* invalidate the old packet */
		g_PacketCache[nextId].length = 0;
		g_NumPacketsInCache--;
		assert(g_NumPacketsInCache >= 0);
	}

	/* process a new packet, then update finger index */	
	rbdrs = doRabin(data, skblen, &numBoundaries);
	int lastOffset = 0;
	char redundancyTest[MAX_PKT_SIZE];
	memset(redundancyTest, 0, sizeof(redundancyTest));
	for (i = 0; i < numBoundaries; i++) {
		int offset = rbdrs[i].offset;
		int rb_size = offset - lastOffset;
		if (rb_size < g_WindowSize) {
			#if 0
			fprintf(stderr, "skip too small chunk: %d bytes\n",
					rb_size);
			#endif
			continue;
		}

		u_int64 finger = rbdrs[i].finger;
		int finger_offset = offset - g_WindowSize;
		assert(finger_offset >= 0);
		lastOffset = offset;

		/* update finger index */
		FingerEntry* fe_val = hashtable_search(g_FingerTable, &finger);
		if (fe_val != NULL) {
			/* find redundancy */
			if (fe_val->pktId == nextId) {
				#if 0
				fprintf(stderr, "self-referencing\n");
				#endif
				continue;
			}

			PacketEntry* pe = &g_PacketCache[fe_val->pktId];
			int left = expand(TRUE, (u_char*)pe->data, pe->length,
					fe_val->offset, data, skblen,
					finger_offset);
			int right = expand(FALSE, (u_char*)pe->data, pe->length,
					fe_val->offset, data, skblen,
					finger_offset);
			int start = finger_offset - left;
			assert(start >= 0);
			memset(redundancyTest + start, 1,
					left + g_WindowSize + right);
		}
		else {
			/* make key */
			u_int64* fe_key = malloc(sizeof(u_int64));
			if (fe_key == NULL) {
				fprintf(stderr, "finger key malloc failed\n");
				exit(0);
			}
			memcpy(fe_key, &finger, sizeof(u_int64));

			/* make value */
			fe_val = malloc(sizeof(FingerEntry));
			if (fe_val == NULL) {
				fprintf(stderr, "FingerEntry malloc failed\n");
				exit(0);
			}
			fe_val->pktId = nextId;
			fe_val->offset = finger_offset;

			/* insert it */
			if (hashtable_insert(g_FingerTable, fe_key, fe_val)
					== 0) {
				fprintf(stderr, "finger insert failed\n");
				exit(0);
			}

			assert(hashtable_search(g_FingerTable, &finger)
				!= NULL);
		}
	}

	/* find non-overlapping region */
	char lastFlag = redundancyTest[0];
	int total_count = 0;
	int region_count = 0;
	int overhead_count = 0;
	for (i = 0; i < skblen; i++) {
		if (lastFlag == redundancyTest[i]) {
			/* keep counting */
			region_count++;
		}
		else {
			/* flush the result */
			if (lastFlag == 1) {
				/* redundant region */
				overhead_count++;
			}
			total_count += region_count;

			/* reset the counter */
			region_count = 1;
		}

		lastFlag = redundancyTest[i];

		if (redundancyTest[i] == 1) {
			g_BytesRedundant++;
		}
	}

	/* flush the last result */
	if (lastFlag == 1) {
		/* redundant region */
		overhead_count++;
	}
	total_count += region_count;
	assert(total_count == skblen);

	/* give the overhead */
	g_BytesOverhead += overhead_count * g_Overhead;
	assert(overhead_count >= 0);

	/* update finger index so that it points to the most recent packet */
	for (i = 0; i < numBoundaries; i++) {
		/* update finger index */
		FingerEntry* fe_val = hashtable_search(g_FingerTable,
				&rbdrs[i].finger);
		if (fe_val != NULL) {
			int offset = rbdrs[i].offset;
			int rb_size = offset - lastOffset;
			if (rb_size < g_WindowSize) {
				continue;
			}

			int finger_offset = offset - g_WindowSize;
			assert(finger_offset >= 0);
			lastOffset = offset;

			#if 0
			fprintf(stderr, "update: from %d to %d\n",
					fe_val->pktId, nextId);
			#endif
			fe_val->pktId = nextId;
			fe_val->offset = finger_offset;
		}
	}

	/* update packet cache: FIFO */
	#if 0
	fprintf(stderr, "PktID: %d, %d bytes packet, %d fingers found!\n",
			nextId, skblen, numFingers);
	#endif
	g_PacketCache[nextId].length = skblen;
	assert(skblen > 0);
	assert(skblen < MAX_PKT_SIZE);
	memcpy(g_PacketCache[nextId].data, data, skblen);
	g_CurPacketId = nextId;
	g_NumPacketsInCache++;
	assert(g_NumPacketsInCache <= g_MaxPackets);
	float saving = 100.0 * (g_BytesRedundant - g_BytesOverhead)
		/ g_BytesIP;
	if (g_Verbose) {
		fprintf(stderr, "%lld: %d pkts %d fingers,"
				" %lld total bytes, %lld bytes redundant,"
				" %lld bytes overhead, saving: %.2f%%\n",
				g_NumIPPackets, g_NumPacketsInCache,
				hashtable_count(g_FingerTable),
				g_BytesIP, g_BytesRedundant,
				g_BytesOverhead, saving);
	}
}
/**
 * Get the number of entries in the table of managed interfaces.
 * 
 * @return The number of entries in the table
 */
int
policy_table_entry_count(void)
{
    INSIST(if_table != NULL);
    return hashtable_count(if_table);
}
/**
 * Clean policy table, remove all UNVERIFIED filters and routes.
 * Anything left in the UNVERIFIED state (status) will be deleted.
 */
void
policy_table_clean(void)
{
    policy_table_entry_t * policy = NULL;
    ped_policy_route_t * route_tmp = NULL, * route = NULL;
    struct hashtable_itr * iterator = NULL;
    
    if(hashtable_count(if_table) < 1 || !clean_table ||
       !get_ssd_ready() || !get_ssd_idle()) {
        return; // nothing to do or don't clean yet
    }
    
    junos_trace(PED_TRACEFLAG_HT, "%s", __func__);
    
    iterator = hashtable_iterator(if_table); // mallocs
    INSIST(iterator != NULL);

    // go through all policies
    do {
        policy = hashtable_iterator_value(iterator);
        
        // if we have a broken policy, then remove it
        if(policy->broken) {
            
            // remove and delete filters
            if(policy->filter) {
                remove_filters_from_interface(policy->ifname);
                free(policy->filter);
            }
            
            if(policy->pfd_filter) {
                remove_pfd_filter_from_interface(policy->ifname);
                policy->pfd_filter = FALSE;
            }
            
            // remove and delete routes
            
            route = policy->route;
            while(route) {
                route_tmp = route;      // Save pointer to current route.
                route = route->next;    // Move to the next route.
                if(route_tmp->status != ROUTE_FAILED) {
                    remove_route(route_tmp);
                    if(route->status == ROUTE_PENDING) {
                        --changes_pending;
                    }
                }
                free(route_tmp);        // Free the current route data.
            }

            free(policy);
            
            if(hashtable_iterator_remove(iterator))
                continue;
            else
                break;
        }
        
        // else: policy is not broken 
        // but we will check for routes or filters that don't belong
        
        
        // Check filter:
        if(policy->filter && policy->filter->status == FILTER_UNVERIFIED) {
            free(policy->filter);
            policy->filter = NULL;
            remove_filters_from_interface(policy->ifname);
        }
        
        if(!policy->pfd_filter) {
            policy->pfd_filter = apply_pfd_filter_to_interface(policy->ifname);
        }

        // Check route(s):        
        route = policy->route;
        route_tmp = NULL;
        policy->route = NULL;  // Detach route list temporarily
        
        while(route) {
            
            // check we don't get FAILED routes (in non-broken policies)
            if(route->status == ROUTE_FAILED) {
                // log and crash because this shouldn't happen
                ERRMSG(PED, TRACE_LOG_EMERG, 
                    "%s: Found a route with status=FAILED in a non-broken "
                    "policy. This should not happen.", __func__);
                // abort() is called in the above ERRMSG
            }
            
            // its status should probably be ADDED...
            // unless it's not part of the PSD policy anymore it will be:
            // UNVERIFIED
            if(route->status == ROUTE_UNVERIFIED) {
                // we've received all routes from the PSD, so it is  
                // no longer part of the policy, and we need to delete it
                
                // copy route data into new mem to pass to callback
                // we choose to do this only when policy is not broken
                
                if(route_tmp) { // route_tmp points to last kept route

                    route_tmp->next = route->next;
                    
                    remove_route(route);
                    free(route);
                    
                    // make route point to the next route (in tmp->next) and
                    route = route_tmp->next;
                    
                } else {  // No previous routes that we've kept yet
                    
                    // use tmp ptr to save next
                    route_tmp = route->next;
                    
                    remove_route(route);
                    free(route);
                    
                    // restore route to next route (in tmp) and tmp to NULL
                    route = route_tmp;
                    route_tmp = NULL;
                }
            } else { // a route we are keeping

                if(policy->route == NULL) {
                    policy->route = route;  // First route in the new list
                }
                
                route_tmp = route; // move route_tmp to end
                route = route->next;
            }
        }
        
        // Done checking route(s)
        
    } while (hashtable_iterator_advance(iterator));

    free(iterator);
    
    clean_table = FALSE;
}
Ejemplo n.º 15
0
int32_t get_hashtable_count(void * ht)
{
  return hashtable_count((struct hashtable*)ht);
}