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

📄 tracker.cpp

📁 cTorrent advanced 3.3.2。是对 CTorrent 的一个改进版本。这是目前的最新版。
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "tracker.h"#include <inttypes.h>#include <stdlib.h>#include <string.h>#include <errno.h>#include "peerlist.h"#include "peer.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"#include "console.h"#include "bttime.h"#if !defined(HAVE_SNPRINTF) || !defined(HAVE_RANDOM)#include "compat.h"#endifbtTracker 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_completed = m_f_restart = 0;  m_interval = 15;  m_peers_count = m_seeds_count = 0;  m_connect_refuse_click = 0;  m_last_timestamp = (time_t) 0;  m_prevpeers = 0;  m_report_time = (time_t) 0;  m_report_dl = m_report_ul = m_totaldl = m_totalul = 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 ){    if(arg_verbose && T_READY==m_status)      CONSOLE.Debug("Disconnected from tracker");    CLOSE_SOCKET(m_sock);    m_sock = INVALID_SOCKET;  }  m_request_buffer.Reset();  m_reponse_buffer.Reset();  if( now < m_last_timestamp ) m_last_timestamp = now;  // time reversed  if( m_f_stoped ){    m_status = T_FINISHED;    if( m_f_restart ) Restart();  }  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,"...");    }    CONSOLE.Warning(1, "TRACKER FAILURE REASON: %s", failreason);    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,"...");    }    CONSOLE.Warning(2, "TRACKER WARNING: %s", warnmsg);  }  m_peers_count = m_seeds_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(m_default_interval != (time_t)i) m_default_interval = (time_t)i;  if( decode_query(buf, bufsiz, "complete", (const char**)0, &i,      (int64_t*)0, QUERY_INT) )    m_seeds_count = i;  if( decode_query(buf, bufsiz, "incomplete", (const char**)0, &i,      (int64_t*)0, QUERY_INT) )    m_peers_count = m_seeds_count + i;  else{    if(arg_verbose && 0==m_seeds_count)      CONSOLE.Debug("Tracker did not supply peers count.");    m_peers_count = m_seeds_count;  }  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 ){      memcpy(&addr.sin_addr,ps,sizeof(struct in_addr));      memcpy(&addr.sin_port,ps+sizeof(struct in_addr),sizeof(unsigned short));      if( !Self.IpEquiv(addr) ){        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){      CONSOLE.Warning(3, "warn, detected invalid ip address %s.",tmphost);      continue;    }    if( !Self.IpEquiv(addr) ){      cnt++;      IPQUEUE.Add(&addr);    }  }  if( 0==m_peers_count ){    m_peers_count = cnt + 1;  // include myself    m_f_boguspeercnt = 1;  }else m_f_boguspeercnt = 0;  if(arg_verbose) CONSOLE.Debug("new peers=%d; next check in %d sec",    (int)cnt, (int)m_interval);  return 0;}int btTracker::CheckReponse(){  char *pdata, *format;  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], 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 ){        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);}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;

⌨️ 快捷键说明

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