Exemple #1
0
std::string Cmerkle_tree::compute_root(const_memory_range r)
{
	typedef std::map<int, std::string> t_map;

	t_map map;
	char d[1025];
	for (; r.size(); r += 1024)
	{
		*d = 0;
		memcpy(d + 1, r, min(r.size(), 1024));
		std::string h = Csha1(const_memory_range(d, min(r.size(), 1024) + 1)).read();
		*d = 1;
		int i;
		for (i = 0; map.find(i) != map.end(); i++)
		{
			memcpy(d + 1, map.find(i)->second.c_str(), 20);
			memcpy(d + 21, h.c_str(), 20);
			h = Csha1(const_memory_range(d, 41)).read();
			map.erase(i);
		}
		map[i] = h;
	}
	*d = 1;
	while (map.size() > 1)
	{
		memcpy(d + 21, map.begin()->second.c_str(), 20);
		map.erase(map.begin());
		memcpy(d + 1, map.begin()->second.c_str(), 20);
		map.erase(map.begin());
		map[0] = Csha1(const_memory_range(d, 41)).read();
	}
	return map.empty() ? "" : map.begin()->second;
}
Exemple #2
0
std::string internal_hash(const_memory_range a, const_memory_range b)
{
	assert(a.size() == 20);
	assert(b.size() == 20);
	char d[41];
	*d = 1;
	memcpy(d + 1, a, 20);
	memcpy(d + 21, b, 20);
	return Csha1(const_memory_range(d, 41)).read();
}
Exemple #3
0
long long Ctransaction::connection_id() const
{
	const int cb_s = 12;
	char s[cb_s];
	write_int(8, s, m_server.secret());
	write_int(4, s + 8, m_a.sin_addr.s_addr);
	char d[20];
	(Csha1(data_ref(s, cb_s))).read(d);
	return read_int(8, d);
}
Exemple #4
0
t_user* find_user_by_torrent_pass(str_ref v, str_ref info_hash)
{
	if (v.size() != 32)
		return NULL;
	if (t_user* user = find_user_by_uid(read_int(4, hex_decode(v.substr(0, 8)))))
	{
		if (Csha1((boost::format("%s %d %d %s") % m_config.m_torrent_pass_private_key % user->torrent_pass_version % user->uid % info_hash).str()).read().substr(0, 12) == hex_decode(v.substr(8, 24)))
			return user;
	}
	return find_ptr2(m_users_torrent_passes, to_array<char, 32>(v));
}
Exemple #5
0
void Cdlg_make_torrent::OnSave()
{
	if (!UpdateData())
		return;
	m_name.TrimRight(" ");
	m_tracker.TrimRight(" ");
	CFileDialog dlg(false, "torrent", m_name + ".torrent", OFN_ENABLESIZING | OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT | OFN_PATHMUSTEXIST, "Torrents|*.torrent|", this);
	if (IDOK != dlg.DoModal())
		return;
	CWaitCursor wc;
	AfxGetApp()->WriteProfileString(m_strRegStore, "tracker", m_tracker);
	AfxGetApp()->WriteProfileString(m_strRegStore, "trackers", m_trackers);
	AfxGetApp()->WriteProfileInt(m_strRegStore, "use_merkle", m_use_merkle);
	int cb_piece = 1 << 20;
	if (!m_use_merkle)
	{
		long long cb_total = 0;
		for (t_map::const_iterator i = m_map.begin(); i != m_map.end(); i++)
			cb_total += i->second.size;
		cb_piece = 256 << 10;
		while (cb_total / cb_piece > 4 << 10)
			cb_piece <<= 1;
	}
	typedef std::set<std::string> t_set;
	t_set set;
	for (t_map::const_iterator i = m_map.begin(); i != m_map.end(); i++)
		set.insert(i->second.name);
	Cbvalue files;
	std::string pieces;
	Cvirtual_binary d;
	byte* w = d.write_start(cb_piece);
	for (t_set::const_iterator i = set.begin(); i != set.end(); i++)
	{
		int f = open(i->c_str(), _O_BINARY | _O_RDONLY);
		if (!f)
			continue;
		long long cb_f = 0;
		std::string merkle_hash;
		int cb_d;
		if (m_use_merkle)
		{
			typedef std::map<int, std::string> t_map;

			t_map map;
			char d[1025];
			while (cb_d = read(f, d + 1, 1024))
			{
				if (cb_d < 0)
					break;
				*d = 0;
				std::string h = Csha1(const_memory_range(d, cb_d + 1)).read();
				*d = 1;
				int i;
				for (i = 0; map.find(i) != map.end(); i++)
				{
					memcpy(d + 1, map.find(i)->second.c_str(), 20);
					memcpy(d + 21, h.c_str(), 20);
					h = Csha1(const_memory_range(d, 41)).read();
					map.erase(i);
				}
				map[i] = h;
				cb_f += cb_d;
			}
			*d = 1;
			while (map.size() > 1)
			{
				memcpy(d + 21, map.begin()->second.c_str(), 20);
				map.erase(map.begin());
				memcpy(d + 1, map.begin()->second.c_str(), 20);
				map.erase(map.begin());
				map[0] = Csha1(const_memory_range(d, 41)).read();
			}
			if (!map.empty())
				merkle_hash = map.begin()->second;
		}
		else
		{
			while (cb_d = read(f, w, d.end() - w))
			{
				if (cb_d < 0)
					break;
				w += cb_d;
				if (w == d.end())
				{
					pieces += Csha1(const_memory_range(d, w - d)).read();
					w = d.data_edit();
				}
				cb_f += cb_d;
			}
		}
		close(f);
		files.l(merkle_hash.empty()
			? Cbvalue().d(bts_length, cb_f).d(bts_path, Cbvalue().l(base_name(*i)))
			: Cbvalue().d(bts_merkle_hash, merkle_hash).d(bts_length, cb_f).d(bts_path, Cbvalue().l(base_name(*i))));
	}
	if (w != d)
		pieces += Csha1(const_memory_range(d, w - d)).read();
	Cbvalue info;
	info.d(bts_piece_length, cb_piece);
	if (!pieces.empty())
		info.d(bts_pieces, pieces);
	if (m_map.size() == 1)
	{
		if (m_use_merkle)
			info.d(bts_merkle_hash, files.l().front()[bts_merkle_hash]);
		info.d(bts_length, files.l().front()[bts_length]);
		info.d(bts_name, files.l().front()[bts_path].l().front());
	}
	else
	{
		info.d(bts_files, files);
		info.d(bts_name, static_cast<std::string>(m_name));
	}
	Cbvalue torrent;
	torrent.d(bts_announce, static_cast<std::string>(m_tracker));
	if (!m_trackers.IsEmpty())
		torrent.d(bts_announce_list, parse_trackers(static_cast<std::string>(m_trackers)));
	torrent.d(bts_info, info);
	Cvirtual_binary s = torrent.read();
	if (m_use_merkle)
		s = gzip(s);
	s.save(static_cast<std::string>(dlg.GetPathName()));
	m_torrent_fname = dlg.GetPathName();
	EndDialog(IDOK);
}
Exemple #6
0
int main(int argc, char* argv[])
{
	time_t t = time(NULL);
	if (argc < 2)
	{
		std::cerr << "Usage: " << argv[0] << " <file> <tracker> [--v1]" << std::endl;
		return 1;
	}
	std::string tracker = argc >= 3 ? argv[2] : "udp://localhost:2710";
	bool use_merkle = argc >= 4 ? strcmp(argv[3], "--v1") : true; // set to false for a non-merkle torrent
	insert(argv[1]);
	// use 1 mbyte pieces by default
	int cb_piece = 1 << 20;
	if (!use_merkle)
	{
		// find optimal piece size for a non-merkle torrent
		long long cb_total = 0;
		for (t_map::const_iterator i = g_map.begin(); i != g_map.end(); i++)
			cb_total += i->second.size;
		cb_piece = 256 << 10;
		while (cb_total / cb_piece > 4 << 10)
			cb_piece <<= 1;
	}
	Cbvalue files;
	std::string pieces;
	Cvirtual_binary d;
	byte* w = d.write_start(cb_piece);
	for (t_map::const_iterator i = g_map.begin(); i != g_map.end(); i++)
	{
		int f = open(i->second.name.c_str(), O_BINARY | O_RDONLY);
		if (!f)
			continue;
		long long cb_f = 0;
		std::string merkle_hash;
		int cb_d;
		if (use_merkle)
		{
			// calculate merkle root hash as explained in XBT Make Merkle Tree.cpp
			typedef std::map<int, std::string> t_map;

			t_map map;
			char d[1025];
			while (cb_d = read(f, d + 1, 1024))
			{
				if (cb_d < 0)
					break;
				*d = 0;
				std::string h = Csha1(const_memory_range(d, cb_d + 1)).read();
				*d = 1;
				int i;
				for (i = 0; map.find(i) != map.end(); i++)
				{
					memcpy(d + 1, map.find(i)->second.c_str(), 20);
					memcpy(d + 21, h.c_str(), 20);
					h = Csha1(const_memory_range(d, 41)).read();
					map.erase(i);
				}
				map[i] = h;
				cb_f += cb_d;
			}
			*d = 1;
			while (map.size() > 1)
			{
				memcpy(d + 21, map.begin()->second.c_str(), 20);
				map.erase(map.begin());
				memcpy(d + 1, map.begin()->second.c_str(), 20);
				map.erase(map.begin());
				map[0] = Csha1(const_memory_range(d, 41)).read();
			}
			if (!map.empty())
				merkle_hash = map.begin()->second;
		}
		else
		{
			// calculate piece hashes
			while (cb_d = read(f, w, d.data_end() - w))
			{
				if (cb_d < 0)
					break;
				w += cb_d;
				if (w == d.data_end())
				{
					pieces += Csha1(const_memory_range(d, w - d)).read();
					w = d.data_edit();
				}
				cb_f += cb_d;
			}
		}
		close(f);
		// add file to files key
		files.l(merkle_hash.empty()
			? Cbvalue().d(bts_length, cb_f).d(bts_path, Cbvalue().l(base_name(i->second.name)))
			: Cbvalue().d(bts_merkle_hash, merkle_hash).d(bts_length, cb_f).d(bts_path, Cbvalue().l(base_name(i->second.name))));
	}
	if (w != d)
		pieces += Csha1(const_memory_range(d, w - d)).read();
	Cbvalue info;
	info.d(bts_piece_length, cb_piece);
	if (!pieces.empty())
		info.d(bts_pieces, pieces);
	if (g_map.size() == 1)
	{
		// single-file torrent
		if (use_merkle)
			info.d(bts_merkle_hash, files.l().front().d(bts_merkle_hash));
		info.d(bts_length, files.l().front().d(bts_length));
		info.d(bts_name, files.l().front().d(bts_path).l().front());
	}
	else
	{
		// multi-file torrent
		info.d(bts_files, files);
		info.d(bts_name, g_name);
	}
	Cbvalue torrent;
	torrent.d(bts_announce, tracker);
	torrent.d(bts_info, info);
	Cvirtual_binary s = torrent.read();
	if (use_merkle)
		s = gzip(s);
	s.save(g_name + ".torrent");
	std::cout << time(NULL) - t << " s" << std::endl;
	return 0;
}
Exemple #7
0
bool Cbt_hasher::run(Cbt_file& f)
{
	if (m_i >= f.m_pieces.size())
		return false;
	if (!m_i)
		m_sub_file = f.m_sub_files.begin();
	Cbt_piece& piece = f.m_pieces[m_i];
	Cvirtual_binary d;
	if (m_validate)
	{
		if (f.m_merkle)
		{
			bool root_valid = m_sub_file->merkle_tree().root().string() == m_sub_file->merkle_hash();
			d.write_start(piece.size());
			piece.valid(!f.read_data(f.mcb_piece * m_i, d));
			for (const byte* r = d; r < d.end(); r += 0x8000)
			{
				std::string h = Cmerkle_tree::compute_root(const_memory_range(r, std::min(r + 0x8000, d.end())));
				if (root_valid)
				{
					if (piece.valid() && (!m_sub_file->merkle_tree().has(m_j) || h != m_sub_file->merkle_tree().get(m_j).string()))
						piece.valid(false);
				}
				else
					m_sub_file->merkle_tree().set(m_j, h);
				m_j++;
			}
		}
		else
		{
			d.write_start(piece.size());
			piece.valid(!f.read_data(f.mcb_piece * m_i, d)
				&& !memcmp(Csha1(d).read().data(), piece.m_hash, 20));
		}
	}
	if (!piece.valid())
		f.m_left += piece.size();
	int cb0 = piece.size();
	while (cb0)
	{
		int cb1 = min(cb0, m_sub_file->size() - m_offset);
		if (!piece.valid())
			m_sub_file->left(m_sub_file->left() + cb1);
		cb0 -= cb1;
		m_offset += cb1;
		if (m_offset == m_sub_file->size())
		{
			if (f.m_merkle && m_sub_file->merkle_tree().root().string() != m_sub_file->merkle_hash())
			{
				Cbt_piece* piece = &f.m_pieces.front() + m_sub_file->offset() / f.mcb_piece;
				for (int i = 0; i < m_sub_file->c_pieces(f.mcb_piece); i++)
				{
					if (piece->valid())
						f.m_left += piece->size();
					piece->valid(false);
					piece++;
				}
				m_sub_file->left(m_sub_file->size());
				m_sub_file->merkle_tree().invalidate();
				m_sub_file->merkle_tree().root(m_sub_file->merkle_hash());
			}
			if (!m_sub_file->left())
			{
				m_sub_file->close();
				m_sub_file->open(f.m_name, O_RDONLY);
			}
			m_j = 0;
			m_offset = 0;
			m_sub_file++;
		}
	}
	m_i++;
	return true;
}