Exemple #1
0
void Ctransaction::send_scrape(data_ref r)
{
	if (read_int(8, &r[uti_connection_id], r.end()) != connection_id())
		return;
	if (!m_server.config().m_anonymous_scrape)
	{
		send_error(r, "access denied");
		return;
	}
	const int cb_d = 2 << 10;
	char d[cb_d];
	write_int(4, d + uto_action, uta_scrape);
	write_int(4, d + uto_transaction_id, read_int(4, &r[uti_transaction_id], r.end()));
	char* w = d + utos_size;
  for (r.advance_begin(utis_size); r.size() >= 20 && w + 12 <= d + cb_d; r.advance_begin(20))
	{
		if (const Cserver::t_torrent* t = m_server.torrent(r.substr(0, 20).s()))
		{
			w = write_int(4, w, t->seeders);
			w = write_int(4, w, t->completed);
			w = write_int(4, w, t->leechers);
		}
		else
		{
			w = write_int(4, w, 0);
			w = write_int(4, w, 0);
			w = write_int(4, w, 0);
		}
	}
	m_server.stats().scraped_udp++;
	send(data_ref(d, w));
}
Exemple #2
0
void Ctransaction::send_connect(data_ref r)
{
	if (read_int(8, &r[uti_connection_id], r.end()) != 0x41727101980ll)
		return;
	const int cb_d = 2 << 10;
	char d[cb_d];
	write_int(4, d + uto_action, uta_connect);
	write_int(4, d + uto_transaction_id, read_int(4, &r[uti_transaction_id], r.end()));
	write_int(8, d + utoc_connection_id, connection_id());
	send(data_ref(d, utoc_size));
}
Exemple #3
0
void Ctransaction::send_announce(data_ref r)
{
	if (read_int(8, &r[uti_connection_id], r.end()) != connection_id())
		return;
	if (!m_server.config().m_anonymous_announce)
	{
		send_error(r, "access denied");
		return;
	}
	Ctracker_input ti;
	ti.m_downloaded = read_int(8, &r[utia_downloaded], r.end());
	ti.m_event = static_cast<Ctracker_input::t_event>(read_int(4, &r[utia_event], r.end()));
	ti.m_info_hash.assign(reinterpret_cast<const char*>(&r[utia_info_hash]), 20);
	ti.m_ipa = read_int(4, &r[utia_ipa], r.end()) && is_private_ipa(m_a.sin_addr.s_addr)
		? htonl(read_int(4, &r[utia_ipa], r.end()))
		: m_a.sin_addr.s_addr;
	ti.m_left = read_int(8, &r[utia_left], r.end());
	ti.m_num_want = read_int(4, &r[utia_num_want], r.end());
	ti.m_peer_id.assign(reinterpret_cast<const char*>(&r[utia_peer_id]), 20);
	ti.m_port = htons(read_int(2, &r[utia_port], r.end()));
	ti.m_uploaded = read_int(8, &r[utia_uploaded], r.end());
	std::string error = m_server.insert_peer(ti, true, NULL);
	if (!error.empty())
	{
		send_error(r, error);
		return;
	}
	const Cserver::t_torrent* torrent = m_server.torrent(ti.m_info_hash);
	if (!torrent)
		return;
	const int cb_d = 2 << 10;
	char d[cb_d];
	write_int(4, d + uto_action, uta_announce);
	write_int(4, d + uto_transaction_id, read_int(4, &r[uti_transaction_id], r.end()));
	write_int(4, d + utoa_interval, m_server.config().m_announce_interval);
	write_int(4, d + utoa_leechers, torrent->leechers);
	write_int(4, d + utoa_seeders, torrent->seeders);
	std::string peers = torrent->select_peers(ti);
	memcpy(d + utoa_size, peers.data(), peers.size());
	send(data_ref(d, d + utoa_size + peers.size()));
}
Exemple #4
0
int main(int argc, char **argv){
	/* extract program name from path. e.g. /path/to/MArCd -> MArCd */
	const char* separator = strrchr(argv[0], '/');
	if ( separator ){
		program_name = separator + 1;
	} else {
		program_name = argv[0];
	}

	struct filter filter;
	if ( filter_from_argv(&argc, argv, &filter) != 0 ){
		return 0; /* error already shown */
	}

	int op, option_index = -1;
	while ( (op = getopt_long(argc, argv, shortopts, longopts, &option_index)) != -1 ){
		switch (op){
		case 0:   /* long opt */
		case '?': /* unknown opt */
			break;

		case '1':
		case '2':
		case '3':
		case '4':
		{
			const unsigned int mask = (7<<FORMAT_LAYER_BIT);
			flags &= ~mask; /* reset all layer bits */
			flags |= (op-'0')<<FORMAT_LAYER_BIT;
			break;
		}

		case 'd': /* --calender */
			flags |= FORMAT_DATE_STR | FORMAT_DATE_UTC;
			break;

		case 'D': /* --localtime */
			flags |= FORMAT_DATE_STR | FORMAT_DATE_LOCALTIME;
			break;

		case 'a': /* --absolute */
			flags &= ~FORMAT_REL_TIMESTAMP;
			break;

		case 'r': /* --relative */
			flags |= FORMAT_REL_TIMESTAMP;
			break;

		case 'H': /* --headers */
			flags |= FORMAT_HEADER;
			break;

		case 'p': /* --packets */
			max_packets = atoi(optarg);
			break;

		case 'c': /* --packets */
			max_matched_packets = atoi(optarg);
			break;

		case 't': /* --timeout */
		{
			int tmp = atoi(optarg);
			timeout.tv_sec  = tmp / 1000;
			timeout.tv_usec = tmp % 1000 * 1000;
		}
		break;

		case 'x': /* --hexdump */
			flags |= FORMAT_HEXDUMP;
			break;

		case 'i': /* --iface */
			iface = optarg;
			break;

		case ARGUMENT_VERSION: /* --version */
			show_version();
			return 0;

		case 'h': /* --help */
			show_usage();
			return 0;

		default:
			fprintf (stderr, "%s: argument '-%c' declared but not handled\n", argv[0], op);
		}
	}

	int ret;

	/* Open stream(s) */
	struct stream* stream;
	if ( (ret=stream_from_getopt(&stream, argv, optind, argc, iface, "-", program_name, 0)) != 0 ) {
		return ret; /* Error already shown */
	}
	const stream_stat_t* stat = stream_get_stat(stream);
	stream_print_info(stream, stderr);

	/* handle C-c */
	signal(SIGINT, handle_sigint);

	/* setup formatter */
	struct format format;
	format_setup(&format, flags);

	uint64_t matched = 0;
	while ( keep_running ) {
		/* A short timeout is used to allow the application to "breathe", i.e
		 * terminate if SIGINT was received. */
		struct timeval tv = timeout;

		/* Read the next packet */
		cap_head* cp;
		ret = stream_read(stream, &cp, NULL, &tv);
		if ( ret == EAGAIN ){
			continue; /* timeout */
		} else if ( ret != 0 ){
			break; /* shutdown or error */
		}

		/* identify connection even if filter doesn't match so id will be
		 * deterministic when changing the filter */
		connection_id(cp);

		if ( filter_match(&filter, cp->payload, cp) ){
			format_pkg(stdout, &format, cp);
			matched++;
		} else {
			format_ignore(stdout, &format, cp);
		}

		if ( max_packets > 0 && stat->matched >= max_packets) {
			/* Read enough pkts lets break. */
			break;
		}
		if ( max_matched_packets > 0 && matched >= max_matched_packets) {
			/* Read enough pkts lets break. */
			break;
		}
	}

	/* if ret == -1 the stream was closed properly (e.g EOF or TCP shutdown)
	 * In addition EINTR should not give any errors because it is implied when the
	 * user presses C-c */
	if ( ret > 0 && ret != EINTR ){
		fprintf(stderr, "stream_read() returned 0x%08X: %s\n", ret, caputils_error_string(ret));
	}

	/* Write stats */
	fprintf(stderr, "%"PRIu64" packets read.\n", stat->read);
	fprintf(stderr, "%"PRIu64" packets matched filter.\n", matched);

	/* Release resources */
	stream_close(stream);
	filter_close(&filter);

	return 0;
}