📄 tracker.cpp
字号:
"The file is not registered on this tracker, or it may have been removed."); CONSOLE.Warning(2, "IF YOU SEE THIS MESSAGE FOR A LONG TIME AND DOWNLOAD DOESN'T BEGIN, RECOMMEND YOU STOP NOW!!!"); CONSOLE.Warning(0, "Tracker reponse data DUMP:"); if( pdata && dlen ) // write(STDERR_FILENO, pdata, dlen); CONSOLE.Warning(0, "%s", pdata); CONSOLE.Warning(0, "== DUMP OVER=="); return -1; }else return 0; } if ( !pdata ){ CONSOLE.Warning(2, "warn, peers list received from tracker is empty."); return 0; } if( !m_f_started ) m_f_started = 1; m_connect_refuse_click = 0; m_ok_click++; return _UpdatePeerList(pdata,dlen);}int btTracker::Initial(){ char ih_buf[20 * 3 + 1],pi_buf[20 * 3 + 1],tmppath[MAXPATHLEN]; char *format; if(Http_url_analyse(BTCONTENT.GetAnnounce(),m_host,&m_port,m_path) < 0){ CONSOLE.Warning(1, "error, invalid tracker url format!"); return -1; } strcpy(tmppath,m_path); if(strchr(m_path, '?')) format=REQ_URL_P1A_FMT; else format=REQ_URL_P1_FMT; char chars[37] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; for(int i=0; i<8; i++) m_key[i] = chars[random()%36]; m_key[8] = 0; if(MAXPATHLEN < snprintf((char*)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; } /* get local ip address */ // 1st: if behind firewall, this only gets local side { struct sockaddr_in addr; socklen_t addrlen = sizeof(struct sockaddr_in); if(getsockname(m_sock,(struct sockaddr*)&addr,&addrlen) == 0) Self.SetIp(addr); } // 2nd: better to use addr of our domain { struct sockaddr_in addr; struct hostent *h; char hostname[128]; char *hostdots[2]={0,0}, *hdptr=hostname; if (gethostname(hostname, 128) == -1) return -1;// CONSOLE.Print("%s", hostname); while(*hdptr) if(*hdptr++ == '.') { hostdots[0] = hostdots[1]; hostdots[1] = hdptr; } if (hostdots[0] == 0) return -1;// CONSOLE.Print("%s", hostdots[0]); if ((h = gethostbyname(hostdots[0])) == NULL) return -1; //CONSOLE.Print("Host domain : %s", h->h_name); //CONSOLE.Print("IP Address : %s", inet_ntoa(*((struct in_addr *)h->h_addr))); memcpy(&addr.sin_addr,h->h_addr,sizeof(struct in_addr)); Self.SetIp(addr); } return 0;}int btTracker::Connect(){ ssize_t r; time(&m_last_timestamp); if(_s2sin(m_host,m_port,&m_sin) < 0) { CONSOLE.Warning(2, "warn, get tracker's ip address failed."); return -1; } m_sock = socket(AF_INET,SOCK_STREAM,0); if(INVALID_SOCKET == m_sock) return -1; // we only need to bind if we have specified an ip // we need it to bind here before the connect!!!! if ( cfg_listen_ip != 0 ) { struct sockaddr_in addr; // clear the struct as requested in the manpages memset(&addr,0, sizeof(sockaddr_in)); // set the type addr.sin_family = AF_INET; // we want the system to choose port addr.sin_port = 0; // set the defined ip from the commandline addr.sin_addr.s_addr = cfg_listen_ip; // bind it or return... if(bind(m_sock,(struct sockaddr*)&addr,sizeof(struct sockaddr_in)) != 0){ CONSOLE.Warning(1, "warn, can't set up tracker connection: %s", strerror(errno)); return -1; } } if(setfd_nonblock(m_sock) < 0) {CLOSE_SOCKET(m_sock); return -1; } r = connect_nonb(m_sock,(struct sockaddr*)&m_sin); if( r == -1 ){ CLOSE_SOCKET(m_sock); return -1;} else if( r == -2 ) m_status = T_CONNECTING; else{ if( 0 == SendRequest()) m_status = T_READY; else{ CLOSE_SOCKET(m_sock); return -1;} } return 0;}int btTracker::SendRequest(){ char *event,*str_event[] = {"started","stopped","completed" }; char REQ_BUFFER[2*MAXPATHLEN]; struct sockaddr_in addr; if( m_f_stoped ) event = str_event[1]; /* stopped */ else if( !m_f_started ){ if( BTCONTENT.pBF->IsFull() ) m_f_completed = 1; event = str_event[0]; /* started */ }else if( BTCONTENT.pBF->IsFull() && !m_f_completed ){ if( Self.TotalDL() > 0 ) event = str_event[2]; /* download complete */ else event = (char*) 0; /* interval */ m_f_completed = 1; /* only send download complete once */ }else event = (char*) 0; /* interval */ if(event){ if(MAXPATHLEN < snprintf(REQ_BUFFER,MAXPATHLEN,REQ_URL_P2_FMT, m_path, (unsigned long long)(Self.TotalUL()), (unsigned long long)(Self.TotalDL()), (unsigned long long)(BTCONTENT.GetLeftBytes()), event, (int)cfg_max_peers, m_key)){ return -1; } }else{ if(MAXPATHLEN < snprintf(REQ_BUFFER,MAXPATHLEN,REQ_URL_P3_FMT, m_path, (unsigned long long)(Self.TotalUL()), (unsigned long long)(Self.TotalDL()), (unsigned long long)(BTCONTENT.GetLeftBytes()), (int)cfg_max_peers, m_key)){ return -1; } } if( *m_trackerid && MAXPATHLEN - strlen(m_path) > 11 + strlen(m_trackerid) ) strcat(strcat(m_path, "&trackerid="), m_trackerid); // if we have a tracker hostname (not just an IP), send a Host: header if(_IPsin(m_host, m_port, &addr) < 0){ char REQ_HOST[MAXHOSTNAMELEN]; if(MAXHOSTNAMELEN < snprintf(REQ_HOST,MAXHOSTNAMELEN,"\r\nHost: %s",m_host)) return -1; strcat(REQ_BUFFER, REQ_HOST); } strcat(REQ_BUFFER, "\r\nUser-Agent: "); strcat(REQ_BUFFER, cfg_user_agent); strcat(REQ_BUFFER,"\r\n\r\n"); // hc //CONSOLE.Warning(0, "SendRequest: %s", REQ_BUFFER); if( 0 != m_reponse_buffer.PutFlush(m_sock,REQ_BUFFER,strlen((char*)REQ_BUFFER)) ){ CONSOLE.Warning(2, "warn, send request to tracker failed: %s", strerror(errno)); if( event == str_event[2] ) m_f_completed = 0; // failed sending completion event return -1; } return 0;}int btTracker::IntervalCheck(fd_set *rfdp, fd_set *wfdp){ /* tracker communication */ if( T_FREE == m_status ){ if( now - m_last_timestamp >= m_interval || // Connect to tracker early if we run low on peers. (WORLD.GetPeersCount() < cfg_min_peers && m_prevpeers >= cfg_min_peers && now - m_last_timestamp >= 15) ){ m_prevpeers = WORLD.GetPeersCount(); if(Connect() < 0){ Reset(15); return -1; } FD_SET(m_sock, rfdp); if( m_status == T_CONNECTING ) FD_SET(m_sock, wfdp); }else if( now < m_last_timestamp ) m_last_timestamp = now; }else{ if( m_status == T_CONNECTING ){ FD_SET(m_sock, rfdp); FD_SET(m_sock, wfdp); }else if (INVALID_SOCKET != m_sock){ FD_SET(m_sock, rfdp); } } return m_sock;}int btTracker::SocketReady(fd_set *rfdp, fd_set *wfdp, int *nfds, fd_set *rfdnextp, fd_set *wfdnextp){ if( T_FREE == m_status ) return 0; if( T_CONNECTING == m_status && FD_ISSET(m_sock,wfdp) ){ int error = 0; socklen_t n = sizeof(error); (*nfds)--; FD_CLR(m_sock, wfdnextp); if( FD_ISSET(m_sock, rfdp) ){ (*nfds)--; FD_CLR(m_sock, rfdnextp); } if(getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n) < 0 || error != 0 ){ if( ECONNREFUSED != error ){ CONSOLE.Warning(2, "warn, connect to tracker failed: %s", strerror(error)); }else m_connect_refuse_click++; Reset(15); return -1; }else{ if( SendRequest() == 0 ) m_status = T_READY; else { Reset(15); return -1; } } }else if( T_CONNECTING == m_status && FD_ISSET(m_sock,rfdp) ){ int error = 0; socklen_t n = sizeof(error); (*nfds)--; FD_CLR(m_sock, rfdnextp); getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n); CONSOLE.Warning(2, "warn, connect to tracker failed: %s", strerror(error)); Reset(15); return -1; }else if(INVALID_SOCKET != m_sock && FD_ISSET(m_sock, rfdp) ){ (*nfds)--; FD_CLR(m_sock,rfdnextp); CheckReponse(); } return 0;}void btTracker::Resume(){ m_f_pause = m_f_stoped = 0; if( T_FINISHED == m_status ){ m_status = T_FREE; m_f_started = 0; m_interval = 15; }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -