Exemple #1
0
int btTracker::SendRequest()
{
	struct sockaddr_in addr;
	char REQ_BUFFER[2 * MAXPATHLEN] = {'\0'};
	const char *str_event[] = {"started", "stopped", "completed"};
	char *event;

	if (m_f_stoped)
		event = (char *) str_event[1]; /* stopped */
	else if (!m_f_started) {
		if (BTCONTENT.IsFull())
			m_f_completed = 1;
		event = (char *) str_event[0]; /* started */
	} else if (BTCONTENT.IsFull() && !m_f_completed) {
		if (Self.TotalDL() > 0)
			event = (char *) 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);
	}

	strncat(REQ_BUFFER, "\r\nUser-Agent: ", 14 + 1);
	strncat(REQ_BUFFER, cfg_user_agent, strlen(cfg_user_agent));
	strncat(REQ_BUFFER, "\r\n\r\n", 4 + 1);
	// 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;
}
Exemple #2
0
int btTracker::SendRequest()
{
  enum{
    DT_NONE,
    DT_STARTED,
    DT_STOPPED,
    DT_COMPLETED
  } event = DT_NONE;
  const char *event_str = (char *)0;
  char *req_buffer;
  struct sockaddr_in addr;
  dt_datalen_t totaldl, totalul;
  int r;

  if( !(req_buffer = new char[strlen(m_spec->request) + strlen(m_spec->host) +
                              strlen(*cfg_user_agent) + 256]) ){
    errno = ENOMEM;
    CONSOLE.Warning(1, "Error constructing tracker request:  %s",
      strerror(errno));
    return -1;
  }

  if( m_f_stop ) event = DT_STOPPED;
  else if( !m_f_started ){
    if( BTCONTENT.IsFull() ) m_f_completed = 1;
    event = DT_STARTED;
  }else if( BTCONTENT.IsFull() && !m_f_completed ){
    if( Self.TotalDL() > 0 ) event = DT_COMPLETED;
    m_f_completed = 1;  // only send download complete once
  }

  totaldl = TRACKER.GetTotalDL();
  totalul = TRACKER.GetTotalUL();
  sprintf(req_buffer,
          "%s&uploaded=%llu&downloaded=%llu&left=%llu&compact=1&numwant=%d",
          m_spec->request,
          (unsigned long long)totalul,
          (unsigned long long)totaldl,
          (unsigned long long)BTCONTENT.GetLeftBytes(),
          (int)*cfg_max_peers);
  if( DT_NONE != event ){
    strcat(req_buffer, "&event=");
    event_str = (DT_STARTED == event ? "started" :
                 (DT_STOPPED == event ? "stopped" :
                 (DT_COMPLETED == event ? "completed" : "update")));
    strcat(req_buffer, event_str);
  }
  if( *m_trackerid ){
    strcat(req_buffer, "&trackerid=");
    strcat(req_buffer, m_trackerid);
  }
  strcat(req_buffer, " HTTP/1.0" CRLF);

  // If we have a tracker hostname (not just an IP), send a Host: header
  if( _IPsin(m_spec->host, m_spec->port, &addr) < 0 ){
    strcat(req_buffer, "Host: ");
    strcat(req_buffer, m_spec->host);
    strcat(req_buffer, CRLF);
  }

  strcat(req_buffer, "User-Agent: ");
  strcat(req_buffer, *cfg_user_agent);
  strcat(req_buffer, CRLF);

  strcat(req_buffer, CRLF);
//CONSOLE.Warning(0, "SendRequest: %s", req_buffer);

  r = m_request_buffer.PutFlush(m_sock, req_buffer, strlen(req_buffer));
  delete []req_buffer;
  if( r < 0 ){
    CONSOLE.Warning(2, "warn, send request to tracker at %s failed:  %s",
      m_spec->url, strerror(errno));
    if( event == DT_COMPLETED )
      m_f_completed = 0;  // failed sending completion event
    return -1;
  }else{
    if( 0==m_request_buffer.Count() )
      shutdown(m_sock, SHUT_WR);
    m_report_time = now;
    m_report_dl = totaldl;
    m_report_ul = totalul;
    if(*cfg_verbose){
      CONSOLE.Debug("Reported to tracker:  %llu uploaded, %llu downloaded (%s)",
        (unsigned long long)m_report_ul, (unsigned long long)m_report_dl,
        event_str ? event_str : "update");
    }
  }
  return 0;
}
Exemple #3
0
int btTracker::_UpdatePeerList(char *buf, size_t bufsiz)
{

	char tmphost[MAXHOSTNAMELEN + 1] = {'\0'};
	char warnmsg[1024] = {'\0'};
	char failreason[1024] = {'\0'};

	const char *ps = NULL;
	size_t i, pos, tmpport;
	size_t cnt = 0;

	struct sockaddr_in addr = {0, 0,
		{0},
		{0}};
	memset((void *) &addr, 0, sizeof(addr));

	if (decode_query(buf, bufsiz, "failure reason", &ps, &i, (int64_t *) 0, QUERY_STR)) {

		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)) {

		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;
}
Exemple #4
0
dt_result_t btTracker::ParseResponse(const char *buf, size_t bufsiz)
{
  char tmphost[MAXHOSTNAMELEN];
  const char *ps;
  size_t i, pos, tmpport;
  int64_t bint;
  dt_count_t cnt = 0;

  struct sockaddr_in addr;

  if( decode_query(buf, bufsiz, "failure reason", &ps, &i, (int64_t *)0,
                   DT_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 from %s:  %s", m_spec->url, failreason);
    return DT_FAILURE;
  }
  if( decode_query(buf, bufsiz, "warning message", &ps, &i, (int64_t *)0,
                   DT_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 from %s:  %s", m_spec->url, warnmsg);
  }

  m_peers_count = m_seeds_count = 0;

  if( decode_query(buf, bufsiz, "tracker id", &ps, &i, (int64_t *)0,
                   DT_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, NULL, &bint,
                   DT_QUERY_INT) ){
    m_interval = m_default_interval = (time_t)bint;
  }else{
    CONSOLE.Debug("Tracker at %s did not specify interval.", m_spec->url);
    m_interval = m_default_interval;
  }

  if( decode_query(buf, bufsiz, "complete", (const char **)0, NULL, &bint,
                   DT_QUERY_INT) ){
    m_seeds_count = bint;
  }
  if( decode_query(buf, bufsiz, "incomplete", (const char **)0, NULL, &bint,
                   DT_QUERY_INT) ){
    m_peers_count = m_seeds_count + bint;
  }else{
    if( *cfg_verbose && 0==m_seeds_count )
      CONSOLE.Debug("Tracker at %s did not supply peers count.", m_spec->url);
    m_peers_count = m_seeds_count;
  }

  pos = decode_query(buf, bufsiz, "peers", (const char **)0, (size_t *)0,
                     (int64_t *)0, DT_QUERY_POS);
  if( !pos ){
    CONSOLE.Debug("Tracker at %s did not supply peers.", m_spec->url);
    return DT_FAILURE;
  }
  if( 4 > bufsiz - pos ){
    CONSOLE.Debug("Tracker at %s supplied an invalid peers list.", m_spec->url);
    return DT_FAILURE;
  }

  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, DT_QUERY_STR) ||
        MAXHOSTNAMELEN < i ){
      continue;
    }
    memcpy(tmphost, ps, i);
    tmphost[i] = '\0';

    if( !decode_query(buf, pos, "port", (const char **)0, NULL, &bint,
                      DT_QUERY_INT) ){
      continue;
    }
    tmpport = bint;

    if( !decode_query(buf, pos, "peer id", &ps, &i, (int64_t *)0,
                      DT_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(*cfg_verbose) CONSOLE.Debug("new peers=%d; next check in %d sec [%s]",
    (int)cnt, (int)m_interval, m_spec->url);
  return DT_SUCCESS;
}