📄 tracker.cpp
字号:
#include "tracker.h"#ifndef WINDOWS#include <unistd.h>#include <sys/time.h>#include <time.h>#include <netdb.h>#endif#include <stdlib.h>#include <string.h>#include <errno.h>#include "peerlist.h"#include "httpencode.h"#include "bencode.h"#include "setnonblock.h"#include "connect_nonb.h"#include "btcontent.h"#include "iplist.h"#include "btconfig.h"#include "ctcs.h"btTracker Tracker;btTracker::btTracker(){ memset(m_host,0,MAXHOSTNAMELEN); memset(m_path,0,MAXPATHLEN); memset(m_trackerid,0,PEER_ID_LEN+1); m_sock = INVALID_SOCKET; m_port = 80; m_status = T_FREE; m_f_started = m_f_stoped = m_f_pause = m_f_completed = 0; m_f_softquit = m_f_restart = 0; m_interval = 15; m_connect_refuse_click = 0; m_last_timestamp = (time_t) 0; m_prevpeers = 0;}btTracker::~btTracker(){ if( m_sock != INVALID_SOCKET) CLOSE_SOCKET(m_sock);}void btTracker::Reset(time_t new_interval){ if(new_interval) m_interval = new_interval; if( INVALID_SOCKET != m_sock ){ CLOSE_SOCKET(m_sock); m_sock = INVALID_SOCKET; } m_reponse_buffer.Reset(); time(&m_last_timestamp); if (m_f_stoped){ m_status = T_FINISHED; if( m_f_restart ) Resume(); } else m_status = T_FREE;}int btTracker:: _IPsin(char *h, int p, struct sockaddr_in *psin){ psin->sin_family = AF_INET; psin->sin_port = htons(p); psin->sin_addr.s_addr = inet_addr(h); return ( psin->sin_addr.s_addr == INADDR_NONE ) ? -1 : 0;}int btTracker:: _s2sin(char *h,int p,struct sockaddr_in *psin){ psin->sin_family = AF_INET; psin->sin_port = htons(p); if( h ){ psin->sin_addr.s_addr = inet_addr(h); if(psin->sin_addr.s_addr == INADDR_NONE){ struct hostent *ph = gethostbyname(h); if( !ph || ph->h_addrtype != AF_INET){ memset(psin,0,sizeof(struct sockaddr_in)); return -1; } memcpy(&psin->sin_addr,ph->h_addr_list[0],sizeof(struct in_addr)); } }else psin->sin_addr.s_addr = htonl(INADDR_ANY); return 0;}int btTracker::_UpdatePeerList(char *buf,size_t bufsiz){ char tmphost[MAXHOSTNAMELEN]; const char *ps; size_t i,pos,tmpport; size_t cnt = 0; struct sockaddr_in addr; if( decode_query(buf,bufsiz,"failure reason",&ps,&i,(int64_t*) 0,QUERY_STR) ){ char failreason[1024]; if( i < 1024 ){ memcpy(failreason, ps, i); failreason[i] = '\0'; }else{ memcpy(failreason, ps, 1000); failreason[1000] = '\0'; strcat(failreason,"..."); } fprintf(stderr,"TRACKER FAILURE REASON: %s\n",failreason); if(arg_ctcs){ char ctcsinfo[1048]; snprintf(ctcsinfo,1048,"TRACKER FAILURE REASON: %s",failreason); CTCS.Send_Info(ctcsinfo); } return -1; } if( decode_query(buf,bufsiz,"warning message",&ps,&i,(int64_t*) 0,QUERY_STR) ){ char warnmsg[1024]; if( i < 1024 ){ memcpy(warnmsg, ps, i); warnmsg[i] = '\0'; }else{ memcpy(warnmsg, ps, 1000); warnmsg[1000] = '\0'; strcat(warnmsg,"..."); } fprintf(stderr,"TRACKER WARNING: %s\n",warnmsg); if(arg_ctcs){ char ctcsinfo[1048]; snprintf(ctcsinfo,1048,"TRACKER WARNING: %s",warnmsg); CTCS.Send_Info(ctcsinfo); } } m_peers_count = 0; if( decode_query(buf,bufsiz,"tracker id",&ps,&i,(int64_t*) 0,QUERY_STR) ){ if( i <= PEER_ID_LEN ){ memcpy(m_trackerid, ps, i); m_trackerid[i] = '\0'; }else{ memcpy(m_trackerid, ps, PEER_ID_LEN); m_trackerid[PEER_ID_LEN] = '\0'; } } if(!decode_query(buf,bufsiz,"interval",(const char**) 0,&i,(int64_t*) 0,QUERY_INT)){return -1;} if(m_interval != (time_t)i) m_interval = (time_t)i; if(decode_query(buf,bufsiz,"complete",(const char**) 0,&i,(int64_t*) 0,QUERY_INT)) { m_peers_count += i; } if(decode_query(buf,bufsiz,"incomplete",(const char**) 0,&i,(int64_t*) 0,QUERY_INT)) { m_peers_count += i; } pos = decode_query(buf,bufsiz,"peers",(const char**) 0,(size_t *) 0,(int64_t*) 0,QUERY_POS); if( !pos ){ return -1; } if(4 > bufsiz - pos){return -1; } // peers list ̫С buf += (pos + 1); bufsiz -= (pos + 1); ps = buf-1; if (*ps != 'l') { // binary peers section if not 'l' addr.sin_family = AF_INET; i = 0; while (*ps != ':' ) i = i * 10 + (*ps++ - '0'); i /= 6; ps++; while (i-- > 0) { // if peer is not us if(memcmp(&Self.m_sin.sin_addr,ps,sizeof(struct in_addr))) { memcpy(&addr.sin_addr,ps,sizeof(struct in_addr)); memcpy(&addr.sin_port,ps+sizeof(struct in_addr),sizeof(unsigned short)); cnt++; IPQUEUE.Add(&addr); } ps += 6; } } else for( ;bufsiz && *buf!='e'; buf += pos, bufsiz -= pos ){ pos = decode_dict(buf,bufsiz,(char*) 0); if(!pos) break; if(!decode_query(buf,pos,"ip",&ps,&i,(int64_t*) 0,QUERY_STR) || MAXHOSTNAMELEN < i) continue; memcpy(tmphost,ps,i); tmphost[i] = '\0'; if(!decode_query(buf,pos,"port",(const char**) 0,&tmpport,(int64_t*) 0,QUERY_INT)) continue; if(!decode_query(buf,pos,"peer id",&ps,&i,(int64_t*) 0,QUERY_STR) && i != 20 ) continue; if(_IPsin(tmphost,tmpport,&addr) < 0){ fprintf(stderr,"warn, detected invalid ip address %s.\n",tmphost); continue; } if( !Self.IpEquiv(addr) ){ cnt++; IPQUEUE.Add(&addr); } } if(arg_verbose) fprintf(stderr, "\nnew peers=%u; next check in %u sec\n", cnt, m_interval);// moved to CheckResponse--this function isn't called if no peer data.// if( !cnt ) fprintf(stderr,"warn, peers list received from tracker is empty.\n"); return 0;}int btTracker::CheckReponse(){#define MAX_LINE_SIZ 32 char *pdata, *format; ssize_t r; size_t q, hlen, dlen; r = m_reponse_buffer.FeedIn(m_sock); if( r > 0 ) return 0; q = m_reponse_buffer.Count(); Reset( (-1 == r) ? 15 : 0 ); if( !q ){ int error = 0; socklen_t n = sizeof(error); if(getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n) < 0 || error != 0 ){ fprintf(stderr,"warn, received nothing from tracker! %s\n",strerror(error)); if(arg_ctcs){ char ctcsinfo[256]; snprintf(ctcsinfo,256, "warn, received nothing from tracker! %s",strerror(error)); CTCS.Send_Info(ctcsinfo); } } return -1; } hlen = Http_split(m_reponse_buffer.BasePointer(), q, &pdata,&dlen); if( !hlen ){ fprintf(stderr,"warn, tracker reponse invalid. No html header found.\n"); if(arg_ctcs) CTCS.Send_Info("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],ih_buf[20 * 3 + 1],pi_buf[20 * 3 + 1],tmppath[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){ fprintf(stderr,"warn, tracker redirect to an invalid url %s!\n", redirect); if(arg_ctcs){ char ctcsinfo[256]; snprintf(ctcsinfo,256, "warn, tracker redirect to an invalid url %s!", redirect); CTCS.Send_Info(ctcsinfo); } return -1; } strcpy(tmppath,m_path); if(strchr(m_path, '?')) format=REQ_URL_P1A_FMT; else format=REQ_URL_P1_FMT; if(MAXPATHLEN < snprintf(m_path,MAXPATHLEN,format, tmppath, Http_url_encode(ih_buf, (char*)BTCONTENT.GetInfoHash(), 20), Http_url_encode(pi_buf, (char*)BTCONTENT.GetPeerId(), 20), cfg_listen_port, m_key)){ return -1; } return Connect(); }else if( r >= 400 ){ fprintf(stderr,"\nTracker reponse code >= 400 !!! The file is not registered on this tracker, or it may have been removed. IF YOU SEE THIS MESSAGE FOR A LONG TIME AND DOWNLOAD DOESN'T BEGIN, RECOMMEND YOU STOP NOW!!!\n"); fprintf(stderr,"\nTracker reponse data DUMP:\n"); if( pdata && dlen ) write(STDERR_FILENO, pdata, dlen);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -