void FillMD5Area(uint8_t digest[], uint8_t id, const char passwd[], const uint8_t srcMD5[])
{
	uint8_t	msgbuf[128]; // msgbuf = ‘id‘ + ‘passwd’ + ‘srcMD5’

	int	passlen = strlen(passwd);
	int msglen = 1 + passlen + 16;
	assert(sizeof(msgbuf) >= msglen);

	msgbuf[0] = id;
	memcpy(msgbuf+1, passwd, passlen);
	memcpy(msgbuf+1+passlen, srcMD5, 16);

	//(void)MD5(msgbuf, msglen, digest);
	MD5Calc(msgbuf, msglen, digest);
}
示例#2
0
文件: sync_src.c 项目: javelinjs/VDD
void *sync_src(void *arg)
{
	sync_thread_arg_t *tmparg = arg;
	int sock_fd = tmparg->sock_fd;
	io_sync_ctrl_block_t *dcp = tmparg->dcp;

	int ret;

	//iterate berkeley db, retrieving each record in turn.
	struct list_head key_head;
	struct hashtable *key_hash;
	DBC *cursorp;
	DBT dbt_key, dbt_data;
	dcp->dbp->cursor(dcp->dbp, NULL, &cursorp, 0);
	memset(&dbt_key, 0, sizeof(DBT));
	memset(&dbt_data, 0, sizeof(DBT));

	pthread_mutex_lock(&(dcp->io_lock));
	key_hash = create_hashtable(10000, hash_from_key_fn, keys_equal_fn);
	INIT_LIST_HEAD(&key_head);
	while ((ret = cursorp->c_get(cursorp, &dbt_key, &dbt_data, DB_NEXT)) == 0) {
		key_list_t *tmp = (key_list_t *)malloc(sizeof(key_list_t));
		memcpy(tmp->key, dbt_key.data, KEY_SIZE);
		list_add_tail(&(tmp->list_node), &key_head);
		if (!hashtable_insert(key_hash, tmp->key, tmp)) {
			perror("hash insert error!");
			return NULL;
		}
	}

	//close
	if (cursorp != NULL)
		cursorp->c_close(cursorp);

	pthread_mutex_unlock(&(dcp->io_lock));

	unsigned int max_packet_size = sizeof(msg_sync_t) + SECTION_SIZE;
	unsigned char *sock_buf = (unsigned char *)malloc(max_packet_size);
	DBT key, data;
	MD5_CTX md5_ctx;
	unsigned char tmp[BLOCK_INDEX_SIZE];
	msg_sync_t msg;
	unsigned int bi, fi = 0;
	off_t off1 = 0, off2 = 0;
	key_list_t *valuep;

	void *buf;
	if (posix_memalign(&buf, 512, SECTION_SIZE) != 0) {
		perror("posix_memalign error");
		return NULL;
	}

	int is_data_end = 0, is_block_end = 1;
	while (!is_data_end) {

		if (recv_task(sock_fd, sock_buf, max_packet_size) <= 0) {
			perror("rece_task error");
			return NULL;
		}

		msg = *((msg_sync_t *)sock_buf);
		unsigned char *sock_data;
		switch (msg.type) {
		//recv section md5 code
		case SYNC_SECTION_MD5:
			if (is_block_end || off2 >= BLOCK_SIZE) {
				perror("wrong section msg");
				return NULL;
			}

			sock_data = sock_buf + sizeof(msg_sync_t);

			//read src section data, and calc md5
			if (lseek(dcp->fd[fi], off1 + off2, SEEK_SET) == (off_t)-1) {
				perror("seek error");
				return NULL;
			}

			if (read(dcp->fd[fi], buf, SECTION_SIZE) != SECTION_SIZE) {
				perror("seek error");
				return NULL;
			}

			MD5Calc(&md5_ctx, (unsigned char *)buf, SECTION_SIZE);
#ifdef _SYNC_SRC_DEBUG__
			unsigned int kk;
			for (kk = 0; kk < 16; ++kk)
				printf("%02X", md5_ctx.digest[kk]);
			printf("\n");
#endif
			off2 += SECTION_SIZE;

			// compare to dest md5
			if (memcmp(md5_ctx.digest, sock_data, 16) == 0) {
				SEND_MSG(0, buf, SYNC_SECTION_SAME, "Can't send msg to client");
			} else {
				SEND_MSG(SECTION_SIZE, buf, SYNC_SECTION_DATA, "Can't send msg to client");
			}

			break;

		case SYNC_BLOCK_KEY:
			sock_data = sock_buf + sizeof(msg_sync_t);
#ifdef _SYNC_SRC_DEBUG__
			printf("%u %u ", msg.size, msg.type);
			int jj;
			for (jj = 0; jj < KEY_SIZE; ++jj) {
				printf("%u ", sock_data[jj]);
			}
			printf("\n");
#endif

			if ((valuep = hashtable_remove(key_hash, sock_data)) != NULL) {
				list_del(&(valuep->list_node));
				free(valuep);
			}

			//get block index by key
			memset(&key, 0, sizeof(DBT));
			key.data = sock_data;
			key.size = KEY_SIZE;

			memset(&data, 0, sizeof(DBT));
			data.data = tmp;
			data.ulen = BLOCK_INDEX_SIZE;
			data.flags = DB_DBT_USERMEM;

			ret = dcp->dbp->get(dcp->dbp, NULL, &key, &data, 0);
			if (ret == DB_NOTFOUND) {
				//reply SYNC_BLOCK_DELETE
				SEND_MSG(0, buf, SYNC_BLOCK_DELETE, "Can't send msg to client");
			} else if (ret) {
				printf("dbp->get error - %d\n", ret);
				perror("dbp->get error");
				return NULL;
			} else {
				//reply SYNC_BLOCK_CONTINUE
				bi = *((unsigned int *)tmp);
				fi = *(unsigned int *)(tmp + 4);
				off1 = bi;
				off1 = off1 * BLOCK_SIZE;
				off2 = 0;
				is_block_end = 0;

				SEND_MSG(0, buf, SYNC_BLOCK_CONTINUE,
					"log_deliver send error -can't send msg to client");
			}

			break;

		case SYNC_BLOCK_END:
			if (off2 != BLOCK_SIZE) {
				perror("wrong section");
				return NULL;
			}
			is_block_end = 1;
			SEND_MSG(0, buf, SYNC_OK, "Can't send msg to client");
			break;

		case SYNC_DATA_END:
			is_data_end = 1;
			break;

		default:
			perror("unknown sync msg code");
			return NULL;
		}
	}

   	//destroy hashtable but not free key and value
    hashtable_destroy(key_hash, 2);

	key_list_t *v;
    while (!list_empty(&key_head)) {
    	v = container_of(key_head.next, key_list_t , list_node);
#ifdef _SYNC_SRC_H__
		int kk;
		for (kk = 0; kk < 8; ++kk) printf("%u ", v->key[kk]);
		printf("\n");
#endif

		memset(&key, 0, sizeof(DBT));
		key.data = v->key;
		key.size = KEY_SIZE;

		memset(&data, 0, sizeof(DBT));
		data.data = tmp;
		data.ulen = BLOCK_INDEX_SIZE;
		data.flags = DB_DBT_USERMEM;

		ret = dcp->dbp->get(dcp->dbp, NULL, &key, &data, 0);
		if (ret == DB_NOTFOUND) {
			//do something here
			//key may be deleted
			list_del(key_head.next);
			continue;
		}

		bi = *(unsigned int *)tmp;
		fi = *(unsigned int *)(tmp + 4);

		//send keys
		SEND_MSG(KEY_SIZE, v->key, SYNC_BLOCK_KEY, "Can't send msg to client");

		//recv reply
		RECV_MSG(SYNC_BLOCK_CONTINUE, "recv key_reply error", "return type error");

		//new block, send section data
		off1 = bi;
		off1 = off1 * BLOCK_SIZE;
		for (off2 = 0; off2 < BLOCK_SIZE; off2 += SECTION_SIZE) {
			if (lseek(dcp->fd[fi], off1 + off2, SEEK_SET) == (off_t)-1) {
				perror("seek error");
				return NULL;
			}

			if (read(dcp->fd[fi], buf, SECTION_SIZE) != SECTION_SIZE) {
				perror("read error");
				return NULL;
			}

			//new block, send section data
			SEND_MSG(SECTION_SIZE, buf, SYNC_SECTION_DATA, "send section data failed");

			RECV_MSG(SYNC_OK, "recv section_reply error", "return type error");
		}

		//new block, send block end
		SEND_MSG(0, buf, SYNC_BLOCK_END, "send block end failed");
		
		RECV_MSG(SYNC_OK, "recv data_end_reply", "return type error");

    	list_del(key_head.next);
    }

	//new block, send data end
	SEND_MSG(0, buf, SYNC_DATA_END, "send data end failed");

	close(sock_fd);
	free(sock_buf);

//EXIT:

	return NULL;
}