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)); }
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)); }
void Ctransaction::send_error(data_ref r, const std::string& msg) { const int cb_d = 2 << 10; char d[cb_d]; write_int(4, d + uto_action, uta_error); write_int(4, d + uto_transaction_id, read_int(4, &r[uti_transaction_id], r.end())); memcpy(d + utoe_size, msg.data(), msg.size()); send(data_ref(d, utoe_size + msg.size())); }
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())); }
shared_data xcc_z::gunzip(data_ref s) { if (s.size() < 18) return shared_data(); shared_data d(read_int_le(4, s.end() - 4)); z_stream stream; stream.zalloc = NULL; stream.zfree = NULL; stream.opaque = NULL; stream.next_in = const_cast<unsigned char*>(s.begin()) + 10; stream.avail_in = s.size() - 18; stream.next_out = d.data(); stream.avail_out = d.size(); return stream.next_out && Z_OK == inflateInit2(&stream, -MAX_WBITS) && Z_STREAM_END == inflate(&stream, Z_FINISH) && Z_OK == inflateEnd(&stream) ? d : shared_data(); }