⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tracker.cpp

📁 cTorrent advanced 3.3.2。是对 CTorrent 的一个改进版本。这是目前的最新版。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
      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;    char hostname[MAXHOSTNAMELEN];    if( gethostname(hostname, MAXHOSTNAMELEN) >= 0 ){//    CONSOLE.Debug("hostname: %s", hostname);      if( h = gethostbyname(hostname) ){//      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::IsPrivateAddress(uint32_t addr){  return (addr & htonl(0xff000000)) == htonl(0x0a000000) ||  // 10.x.x.x/8         (addr & htonl(0xfff00000)) == htonl(0xac100000) ||  // 172.16.x.x/12         (addr & htonl(0xffff0000)) == htonl(0xc0a80000) ||  // 192.168.x.x/16         (addr & htonl(0xff000000)) == htonl(0x7f000000);    // 127.x.x.x/8}int btTracker::BuildBaseRequest(){  char ih_buf[20 * 3 + 1], pi_buf[20 * 3 + 1], tmppath[MAXPATHLEN];  const char *format;  strcpy(tmppath,m_path);  if(strchr(m_path, '?'))    format=REQ_URL_P1A_FMT;  else format=REQ_URL_P1_FMT;  char *opt = (char *)0;  if( cfg_public_ip ){    opt = new char[5+strlen(cfg_public_ip)];    strcpy(opt, "&ip=");    strcat(opt, cfg_public_ip);  }else{    struct sockaddr_in addr;    Self.GetAddress(&addr);    if( !IsPrivateAddress(addr.sin_addr.s_addr) ){      opt = new char[20];      strcpy(opt, "&ip=");      strcat(opt, inet_ntoa(addr.sin_addr));    }  }  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),                     opt ? opt : "",                     cfg_listen_port,                     m_key)){    return -1;  }  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(arg_verbose) CONSOLE.Debug("Connected to tracker");    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.IsFull() ) m_f_completed = 1;    event = str_event[0];	/* started */  }else if( BTCONTENT.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 */  char opt1[20] = "&event=";  char opt2[12+PEER_ID_LEN] = "&trackerid=";  if( BTCONTENT.IsFull() ) m_totaldl = Self.TotalDL();  if(MAXPATHLEN < snprintf(REQ_BUFFER,MAXPATHLEN,REQ_URL_P2_FMT,                     m_path,                     event ? strncat(opt1,event,12) : "",                     *m_trackerid ? strncat(opt2,m_trackerid,PEER_ID_LEN) : "",                     (unsigned long long)(m_totalul = Self.TotalUL()),                     (unsigned long long)m_totaldl,                     (unsigned long long)(BTCONTENT.GetLeftBytes()),                     (int)cfg_max_peers)){    return -1;  }  // 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_request_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;  }else{    m_report_time = now;    m_report_dl = m_totaldl;    m_report_ul = m_totalul;    if(arg_verbose)      CONSOLE.Debug("Reported to tracker:  %llu uploaded, %llu downloaded",        (unsigned long long)m_report_ul, (unsigned long long)m_report_dl);  }  return 0;}int btTracker::IntervalCheck(fd_set *rfdp, fd_set *wfdp){  /* tracker communication */  if( T_FREE == m_status ){    if( INVALID_SOCKET != m_sock ){      FD_CLR(m_sock, rfdp);      FD_CLR(m_sock, wfdp);    }    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; // time reversed  }else if( T_CONNECTING == m_status ){    FD_SET(m_sock, rfdp);    FD_SET(m_sock, wfdp);  }else if( INVALID_SOCKET != m_sock ){    FD_SET(m_sock, rfdp);    if( m_request_buffer.Count() ) FD_SET(m_sock, wfdp);  }  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 = errno;    if( error ){      if( ECONNREFUSED == error ){        if(arg_verbose) CONSOLE.Debug("tracker connection refused");        m_connect_refuse_click++;      }else CONSOLE.Warning(2,          "warn, connect to tracker failed:  %s", strerror(error));      Reset(15);      return -1;    }else{      if(arg_verbose) CONSOLE.Debug("Connected to tracker");      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);    if(getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n) < 0)      error = errno;    CONSOLE.Warning(2, "warn, connect to tracker failed:  %s", strerror(error));    Reset(15);    return -1;  }else if( INVALID_SOCKET != m_sock ){    if( FD_ISSET(m_sock, rfdp) ){      (*nfds)--;      FD_CLR(m_sock,rfdnextp);      SOCKET tmp_sock = m_sock;      int r = CheckReponse();      if( INVALID_SOCKET == m_sock ){        if( FD_ISSET(tmp_sock, wfdp) ){          (*nfds)--;          FD_CLR(tmp_sock,wfdnextp);        }        return r;      }    }    if( FD_ISSET(m_sock, wfdp) ){      (*nfds)--;      FD_CLR(m_sock,wfdnextp);      if( m_request_buffer.Count() && m_request_buffer.FlushOut(m_sock) < 0 ){        Reset(15);        return -1;      }    }  }else{  // failsafe    Reset(15);    return -1;  }  return 0;}void btTracker::Restart(){  m_f_stoped = m_f_restart = 0;  if( T_FINISHED == m_status ){    m_status = T_FREE;    m_f_started = 0;    m_interval = 15;  }}void btTracker::SetStoped(){  if( !m_f_started ){    m_f_stoped = 1;    m_status = T_FINISHED;  }else{    Reset(15);    m_f_stoped = 1;  }}void btTracker::RestartTracker(){  SetStoped(); // finish the tracker  // Now we need to wait until the tracker updates (T_FINISHED == m_status),  // then Tracker.Restart().  SetRestart();}size_t btTracker::GetPeersCount() const {  // includes seeds, so must always be >= 1 (myself!)  return (m_peers_count > m_seeds_count) ? m_peers_count :           (GetSeedsCount() + (BTCONTENT.IsFull() ? 0 : 1));}size_t btTracker::GetSeedsCount() const{  return m_seeds_count ? m_seeds_count : (BTCONTENT.IsFull() ? 1 : 0);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -