int btTracker::Initial() { if (Http_url_analyse(BTCONTENT.GetAnnounce(), m_host, &m_port, m_path) < 0) { CONSOLE.Warning(1, "error, invalid tracker url format!"); return -1; } char chars[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for (int i = 0; i < 8; i++) m_key[i] = chars[random() % 36]; m_key[8] = 0; /* get local ip address */ struct sockaddr_in addr; if (cfg_public_ip) { // Get specified public address. if ((addr.sin_addr.s_addr = inet_addr(cfg_public_ip)) == INADDR_NONE) { struct hostent *h; h = gethostbyname(cfg_public_ip); memcpy(&addr.sin_addr, h->h_addr, sizeof(struct in_addr)); } Self.SetIp(addr); goto next_step; } if (cfg_listen_ip) { // Get specified listen address. addr.sin_addr.s_addr = cfg_listen_ip; Self.SetIp(addr); if (!IsPrivateAddress(cfg_listen_ip)) goto next_step; } { // Try to get address corresponding to the hostname. struct hostent *h = NULL; char hostname[MAXHOSTNAMELEN] = {0}; if (gethostname(hostname, MAXHOSTNAMELEN) >= 0) { // CONSOLE.Debug("hostname: %s", hostname); h = gethostbyname(hostname); if (h) { // CONSOLE.Debug("Host name: %s", h->h_name); // CONSOLE.Debug("Address: %s", inet_ntoa(*((struct in_addr *)h->h_addr))); if (!IsPrivateAddress (((struct in_addr *) (h->h_addr))->s_addr) || !cfg_listen_ip) { memcpy(&addr.sin_addr, h->h_addr, sizeof(struct in_addr)); Self.SetIp(addr); } } } } next_step: if (BuildBaseRequest() < 0) return -1; return 0; }
int btTracker::Initial() { if( UrlSplit(m_spec->url, &m_spec->host, &m_spec->port, &m_spec->request) < 0 ){ CONSOLE.Warning(1, "Error parsing tracker URL (%s): %s", m_spec->url, errno ? strerror(errno) : "invalid format"); return -1; } char chars[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for( int i=0; i<8; i++ ) m_key[i] = chars[RandBits(6) % 36]; m_key[8] = 0; if( BuildBaseRequest() < 0 ) return -1; return 0; }
int btTracker::CheckReponse() { char *pdata; ssize_t r; size_t q, hlen, dlen; r = m_reponse_buffer.FeedIn(m_sock); time(&m_last_timestamp); if (r > 0) return 0; // connection is still open; may have more data coming q = m_reponse_buffer.Count(); if (!q) { int error = 0; socklen_t n = sizeof(error); if (getsockopt(m_sock, SOL_SOCKET, SO_ERROR, &error, &n) < 0) error = errno; if (error != 0) CONSOLE.Warning(2, "warn, received nothing from tracker: %s", strerror(error)); else CONSOLE.Warning(2, "warn, received nothing from tracker!"); Reset(15); // try again return -1; } Reset((-1 == r) ? 15 : 0); // can't reset socket before error check hlen = Http_split(m_reponse_buffer.BasePointer(), q, &pdata, &dlen); if (!hlen) { CONSOLE.Warning(2, "warn, tracker reponse invalid. No html header found."); return -1; } r = Http_reponse_code(m_reponse_buffer.BasePointer(), hlen); if (r != 200) { if (r == 301 || r == 302) { char redirect[MAXPATHLEN]; if (Http_get_header (m_reponse_buffer.BasePointer(), hlen, "Location", redirect) < 0) return -1; if (Http_url_analyse(redirect, m_host, &m_port, m_path) < 0) { CONSOLE.Warning(1, "warn, tracker redirected to an invalid url %s", redirect); return -1; } else { char *c = strstr(m_path, "?info_hash="); if (!c) c = strstr(m_path, "&info_hash="); if (c) *c = '\0'; if (arg_verbose) CONSOLE.Debug("tracker redirect to %s", redirect); if (BuildBaseRequest() < 0) return -1; } if (Connect() < 0) { Reset(15); return -1; } else return 0; } else if (r >= 400) { CONSOLE.Warning(2, "Tracker reponse code >= 400 !!!"); CONSOLE.Warning(2, "The file is not registered on this tracker or may have been removed."); CONSOLE.Warning(2, "IF YOU CONTINUE TO GET THIS MESSAGE AND DOWNLOAD DOES NOT BEGIN, PLEASE STOP CTORRENT!"); if (pdata && dlen) { // write(STDERR_FILENO, pdata, dlen); CONSOLE.Warning(0, "Tracker reponse data DUMP:"); CONSOLE.Warning(0, "%s", pdata); CONSOLE.Warning(0, "== DUMP OVER=="); } return -1; } else return 0; } if (!m_f_started) m_f_started = 1; m_connect_refuse_click = 0; m_ok_click++; if (!pdata) { CONSOLE.Warning(2, "warn, peers list received from tracker is empty."); return 0; } return _UpdatePeerList(pdata, dlen); }
dt_result_t btTracker::CheckResponse() { const char *pdata; ssize_t r; size_t q, hlen, dlen; r = m_response_buffer.FeedIn(m_sock); m_last_timestamp = now; if( r > 0 ){ // connection is still open; may have more data coming return DT_NORMAL; } q = m_response_buffer.Count(); if( !q ){ int error = 0; socklen_t n = sizeof(error); if( getsockopt(m_sock, SOL_SOCKET, SO_ERROR, &error, &n) < 0 ) error = errno; if( error ){ CONSOLE.Warning(2, "warn, received nothing from tracker at %s: %s", m_spec->url, strerror(error)); }else{ CONSOLE.Warning(2, "warn, received nothing from tracker at %s", m_spec->url); } Reset(); // try again return DT_FAILURE; } hlen = HttpSplit(m_response_buffer.BasePointer(), q, &pdata, &dlen); if( !hlen ){ CONSOLE.Warning(2, "warn, no HTTP header in response from tracker at %s", m_spec->url); return DT_FAILURE; } r = HttpGetStatusCode(m_response_buffer.BasePointer(), hlen); if( r != 200 ){ if( r == 301 || r == 302 || r == 303 || r == 307 ){ char *tmpurl = (char *)0, *c; tracker_spec *tmpspec; if( HttpGetHeader(m_response_buffer.BasePointer(), hlen, "Location", &tmpurl) < 0 ){ if( errno ){ CONSOLE.Warning(2, "Error parsing redirect response from tracker at %s: %s", m_spec->url, strerror(errno)); }else{ CONSOLE.Warning(2, "warn, redirect with no location from tracker at %s", m_spec->url); } if( tmpurl ) delete []tmpurl; return DT_FAILURE; } if( !(tmpspec = new tracker_spec) ){ CONSOLE.Warning(1, "warn, could not allocate memory for tracker redirect from %s", m_spec->url); errno = ENOMEM; delete []tmpurl; return DT_FAILURE; } if( (c = strstr(tmpurl, "?info_hash=")) || (c = strstr(tmpurl, "&info_hash=")) ){ *c = '\0'; } if( UrlSplit(tmpurl, &tmpspec->host, &tmpspec->port, &tmpspec->request) < 0 ){ CONSOLE.Warning(1, "warn, error parsing redirected tracker URL from %s (%s): %s", m_spec->url, tmpurl, errno ? strerror(errno) : "invalid format"); delete tmpspec; delete []tmpurl; return DT_FAILURE; }else{ CONSOLE.Debug("tracker at %s redirected%s to %s", m_spec->url, (r == 301) ? " permanently" : "", tmpurl); if( (tmpspec->url = new char[strlen(tmpurl) + 1]) ) strcpy(tmpspec->url, tmpurl); else{ CONSOLE.Warning(1, "warn, could not allocate memory for tracker redirect from %s", m_spec->url); errno = ENOMEM; delete tmpspec; delete []tmpurl; return DT_FAILURE; } delete []tmpurl; Reset(); m_redirect = m_spec; m_spec = tmpspec; if( BuildBaseRequest() < 0 ){ delete m_spec; m_spec = m_redirect; m_redirect = (tracker_spec *)0; return DT_FAILURE; }else if( r == 301 ){ // moved permanently delete m_redirect; m_redirect = (tracker_spec *)0; } } if( Connect() < 0 ){ Reset(); delete m_spec; m_spec = m_redirect; m_redirect = (tracker_spec *)0; return DT_FAILURE; }else return DT_NORMAL; }else if( r >= 400 ){ CONSOLE.Warning(2, "Tracker response code %d from %s%s", r, m_spec->url, (r >= 500) ? "" : "; the torrent is not registered on this tracker" " or may have been removed."); if( pdata && dlen ){ // write(STDERR_FILENO, pdata, dlen); char data[dlen + 1]; memcpy(data, pdata, dlen); data[dlen] = '\0'; CONSOLE.Warning(0, "Tracker response data DUMP:"); CONSOLE.Warning(0, "%s", data); CONSOLE.Warning(0, "== DUMP OVER=="); } m_interval = (m_default_interval > 300) ? m_default_interval : 300; m_f_started = 0; return DT_FAILURE; }else{ m_f_started = 0; return DT_FAILURE; } } m_f_started = m_f_stop ? 0 : 1; m_refuse_click = 0; m_ok_click++; if( !pdata ){ CONSOLE.Warning(2, "warn, received no response data from tracker at %s", m_spec->url); return DT_FAILURE; } return ParseResponse(pdata, dlen); }