📄 tracker.cpp
字号:
fprintf(stderr,"\n== DUMP OVER==\n"); return -1; }else return 0; } if ( !pdata ){ fprintf(stderr,"warn, peers list received from tracker is empty.\n"); 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){ fprintf(stderr,"error, invalid tracker url format!\n"); 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 hostent *h; char hostname[128]; char *hostdots[2]={0,0}, *hdptr=hostname; if (gethostname(hostname, 128) == -1) return -1;// printf("%s\n", hostname); while(*hdptr) if(*hdptr++ == '.') { hostdots[0] = hostdots[1]; hostdots[1] = hdptr; } if (hostdots[0] == 0) return -1;// printf("%s\n", hostdots[0]); if ((h = gethostbyname(hostdots[0])) == NULL) return -1; //printf("Host domain : %s\n", h->h_name); //printf("IP Address : %s\n", inet_ntoa(*((struct in_addr *)h->h_addr))); memcpy(&Self.m_sin.sin_addr,h->h_addr,sizeof(struct in_addr)); } return 0;}int btTracker::Connect(){ ssize_t r; time(&m_last_timestamp); if(_s2sin(m_host,m_port,&m_sin) < 0) { fprintf(stderr,"warn, get tracker's ip address failed."); if(arg_ctcs) CTCS.Send_Info("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){ fprintf(stderr, "warn, can't set up tracker connection: %s\n", 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[MAXPATHLEN]; socklen_t addrlen; struct sockaddr_in addr; addrlen = sizeof(struct sockaddr_in); /* get local ip address */ if(getsockname(m_sock,(struct sockaddr*)&addr,&addrlen) < 0){ return -1;}//jc Self.SetIp(addr);// fprintf(stdout,"Old Set Self:");// fprintf(stdout,"%s\n", inet_ntoa(Self.m_sin.sin_addr)); if( m_f_stoped ) event = str_event[1]; /* stopped */ else if( m_f_started == 0 ) { if( BTCONTENT.pBF->IsFull() ) m_f_completed = 1; event = str_event[0]; /* started */ } else if( BTCONTENT.pBF->IsFull() && !m_f_completed){ event = str_event[2]; /* download complete */ 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, Self.TotalUL(), Self.TotalDL(), BTCONTENT.GetLeftBytes(), event, cfg_max_peers, m_key)){ return -1; } }else{ if(MAXPATHLEN < snprintf(REQ_BUFFER,MAXPATHLEN,REQ_URL_P3_FMT, m_path, Self.TotalUL(), Self.TotalDL(), BTCONTENT.GetLeftBytes(), 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(_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\n\r\n"); // hc //fprintf(stderr,"SendRequest: %s\n", REQ_BUFFER); if( 0 != m_reponse_buffer.PutFlush(m_sock,REQ_BUFFER,strlen((char*)REQ_BUFFER))){ fprintf(stderr,"warn, send request to tracker failed. %s\n",strerror(errno)); if(arg_ctcs){ char ctcsinfo[256]; snprintf(ctcsinfo,256, "warn, send request to tracker failed. %s",strerror(errno)); CTCS.Send_Info(ctcsinfo); } return -1; } return 0;}int btTracker::IntervalCheck(const time_t *pnow, fd_set *rfdp, fd_set *wfdp){ /* tracker communication */ if( T_FREE == m_status ){ if( *pnow - m_last_timestamp >= m_interval || // Connect to tracker early if we run low on peers. (WORLD.TotalPeers() < cfg_min_peers && m_prevpeers >= cfg_min_peers && *pnow - m_last_timestamp >= 15) || (m_f_pause && !WORLD.TotalPeers()) ){ m_prevpeers = WORLD.TotalPeers(); if(Connect() < 0){ Reset(15); return -1; } if( m_status == T_CONNECTING ){ FD_SET(m_sock, rfdp); FD_SET(m_sock, wfdp); }else{ FD_SET(m_sock, rfdp); } if( m_f_pause && !WORLD.TotalPeers() ) m_f_stoped = 1; } }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){ 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, wfdp); if(getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n) < 0 || error != 0 ){ if( ECONNREFUSED != error ){ fprintf(stderr,"warn, connect to tracker failed. %s\n",strerror(error)); if(arg_ctcs){ char ctcsinfo[256]; snprintf(ctcsinfo,256, "warn, connect to tracker failed. %s\n",strerror(error)); CTCS.Send_Info(ctcsinfo); } }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, rfdp); getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n); fprintf(stderr,"warn, connect to tracker failed. %s\n",strerror(error)); if(arg_ctcs){ char ctcsinfo[256]; snprintf(ctcsinfo,256, "warn, connect to tracker failed. %s\n",strerror(error)); CTCS.Send_Info(ctcsinfo); } Reset(15); return -1; }else if(INVALID_SOCKET != m_sock && FD_ISSET(m_sock, rfdp) ){ (*nfds)--; FD_CLR(m_sock,rfdp); 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 + -