void Tracker::event_sock_ready2read(network::Socket sock) { if (m_state == TRACKER_STATE_RELEASING) return; try { bool closed; size_t received = m_nm->Socket_recv(sock, m_buf + m_buflen, BUFFER_SIZE - m_buflen, closed); m_buflen += received; process_response(); if (closed) { delete_socket(); if (m_status == TRACKER_STATUS_UPDATING) m_status = TRACKER_STATUS_ERROR; return; } } catch (Exception & e) { delete_socket(); m_status = TRACKER_STATUS_ERROR; logger::LOGGER() << "Tracker ready to read event failure"; } }
void Tracker::forced_releasing() { if (m_state == TRACKER_STATE_FAILURE) return; m_ready2release = true; delete_socket(); }
void Tracker::event_sock_error(network::Socket sock, int errno_) { delete_socket(); if (m_status == TRACKER_STATUS_UPDATING) m_status = TRACKER_STATUS_ERROR; m_ready2release = (m_state == TRACKER_STATE_RELEASING); }
void Gobby::GSelector::set(const net6::socket& sock, net6::io_condition cond) { // Lock mutex - required for connection establishment which happens // in a different thread for the GUI to remain responsive. // After the connection to Glib::signal_io() the main thread may be // woken up immediately by incoming data and call GSelector::set to // send out some data even before the assignment to the // sigc::connection in the connecting thread has been finished! Glib::RecMutex::Lock lock(*m_mutex); map_type::iterator iter = m_map.find(&sock); if(cond != net6::IO_NONE) { if(iter == m_map.end() ) add_socket(sock, cond); else modify_socket(iter, cond); } else if(iter != m_map.end() ) { delete_socket(iter); } }
void Tracker::event_sock_unresolved(network::Socket sock) { if (m_state == TRACKER_STATE_FAILURE) return; m_status = TRACKER_STATUS_UNRESOLVED; delete_socket(); m_ready2release = (m_state == TRACKER_STATE_RELEASING); }
void Tracker::event_sock_timeout(network::Socket sock) { #ifdef BITTORRENT_DEBUG logger::LOGGER() << "Tracker " << m_announce.c_str() << " timeout"; #endif if (m_state == TRACKER_STATE_FAILURE) return; m_status = TRACKER_STATUS_TIMEOUT; delete_socket(); m_ready2release = (m_state == TRACKER_STATE_RELEASING); }
Tracker::~Tracker() { #ifdef BITTORRENT_DEBUG logger::LOGGER() << "Tracker " << m_announce.c_str() << " destructor"; #endif if (m_addr != NULL) delete m_addr; delete_socket(); #ifdef BITTORRENT_DEBUG logger::LOGGER() << "Tracker " << m_announce.c_str() << " destroyed"; #endif }
void Tracker::event_sock_connected(network::Socket sock) { try { if (m_addr == NULL) m_addr = new sockaddr_in; m_nm->Socket_get_addr(sock, *m_addr); send_request(m_event_after_connect); } catch (Exception & e) { logger::LOGGER() << "Tracker " << m_announce.c_str() << " error while sending request"; delete_socket(); m_status = TRACKER_STATUS_ERROR; m_ready2release = (m_state == TRACKER_STATE_RELEASING); } }
socket_t *find_socket( uint16 src_port, uint16 dest_port, int proto ) { socket_t *result = 0; EnterCriticalSection( &router_section ); int i = get_socket_index( src_port, dest_port, proto ); if( i >= 0 ) { result = all_sockets[i]; } else { i = get_socket_index( src_port, proto ); if( i >= 0 ) { delete_socket( all_sockets[i] ); } } LeaveCriticalSection( &router_section ); D(bug("find_socket(%d,%d): %s\r\n", src_port, dest_port, result ? "found" : "not found")); return result; }
void Tracker::prepare2release() { #ifdef BITTORRENT_DEBUG logger::LOGGER() << "Tracker " << m_announce.c_str() << " prepare2release"; #endif if (m_state == TRACKER_STATE_FAILURE) { #ifdef BITTORRENT_DEBUG logger::LOGGER() << "Tracker is fail " << m_announce.c_str() << " prepare2release"; #endif m_ready2release = true; return; } if (send_stopped() != ERR_NO_ERROR) { delete_socket(); m_ready2release = true; } m_state = TRACKER_STATE_RELEASING; }
int Tracker::process_response() { char * rnrn = strchr(m_buf,'\r'); char * data = NULL; ssize_t len = 0; while (rnrn != NULL) { if (strncmp(rnrn, "\r\n\r\n", 4) == 0) { data = rnrn + 4; break; } rnrn = strchr(rnrn + 4,'\r'); } if (data == NULL) { m_status = TRACKER_STATUS_ERROR; logger::LOGGER() << "Tracker invalid response(data == null)"; return ERR_INTERNAL; } len = m_buflen - (data - m_buf); bencode::be_node * response = bencode::decode(data, len, false); if (response == NULL) { m_status = TRACKER_STATUS_ERROR; logger::LOGGER() << "Tracker invalid response(not bencode)"; return ERR_INTERNAL; } //bencode::dump(response); bencode::be_str * b_str = NULL; char * c_str = NULL; m_status = TRACKER_STATUS_OK; m_tracker_failure = ""; if (bencode::get_str(response, "warning message", &b_str) == 0) { c_str = bencode::str2c_str(b_str); m_status = TRACKER_STATUS_SEE_FAILURE_MESSAGE; m_tracker_failure = c_str; delete[] c_str; } if (bencode::get_str(response, "failure reason", &b_str) == 0) { c_str = bencode::str2c_str(b_str); m_status = TRACKER_STATUS_SEE_FAILURE_MESSAGE; m_tracker_failure = c_str; delete[] c_str; } bencode::get_int(response,"interval",&m_interval); bencode::get_int(response,"min interval",&m_min_interval); if (bencode::get_str(response,"tracker id",&b_str) == 0) { c_str = bencode::str2c_str(b_str); m_tracker_id = c_str; delete[] c_str; } bencode::get_int(response,"complete",&m_seeders); bencode::get_int(response,"incomplete",&m_leechers); if (bencode::get_str(response,"peers",&b_str) == 0) { int len = b_str->len; char * t_str = b_str->ptr; if (len % 6 != 0) { bencode::_free(response); m_status = TRACKER_STATUS_ERROR; logger::LOGGER() << "Tracker invalid response(invalid peer list)"; return ERR_INTERNAL; } int peers_count = len / 6; m_peers.clear(); FILE * f = fopen("peers", "wb"); for(int i = 0; i < peers_count; i++) { sockaddr_in addr; memcpy((void*)&addr.sin_addr, (void*)&t_str[i * 6], 4); memcpy(&addr.sin_port, &t_str[i * 6 + 4], 2); addr.sin_family = AF_INET; m_peers.push_back(addr); fwrite((void*)&addr, 1, sizeof(sockaddr_in), f); } fclose(f); } bencode::_free(response); m_buflen = 0; m_torrent->add_seeders(m_peers); delete_socket(); return 0; }