📄 ctcs.cpp
字号:
#ifndef WINDOWS#include <unistd.h>#include <netdb.h>#endif#include <stdlib.h>#include <string.h>#include <errno.h>#include <ctype.h>#include "ctcs.h"#include "btcontent.h"#include "setnonblock.h"#include "connect_nonb.h"#include "tracker.h"#include "peerlist.h"#include "peer.h"#include "btconfig.h"#include "bttime.h"#include "console.h"#define CTCS_PROTOCOL 2#define compset(a,member) ( (a.member==member)? 0 : ((a.member = member)||1) )Ctcs CTCS;Ctcs::Ctcs(){ memset(m_host,0,MAXHOSTNAMELEN); m_sock = INVALID_SOCKET; m_port = 2780; m_status = T_FREE; m_interval = 1; m_protocol = CTCS_PROTOCOL; m_last_timestamp = m_sent_ctstatus_time = m_statustime = (time_t) 0; m_sent_ctstatus = 0; m_sent_ctbw = 0;}Ctcs::~Ctcs(){ if( m_sock != INVALID_SOCKET) CLOSE_SOCKET(m_sock);}void Ctcs::Reset(time_t new_interval){ if(new_interval) m_interval = new_interval; if( INVALID_SOCKET != m_sock ){ CLOSE_SOCKET(m_sock); m_sock = INVALID_SOCKET; } in_buffer.Reset(); out_buffer.Reset(); m_last_timestamp = now; m_sent_ctstatus = 0; m_sent_ctbw = 0; m_status = T_FREE;}// borrowed from tracker.cpp (with changes)int Ctcs:: _s2sin(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); 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)); } return ( psin->sin_addr.s_addr == INADDR_NONE ) ? -1 : 0;}int Ctcs::CheckMessage(){ ssize_t r; size_t q; r = in_buffer.FeedIn(m_sock); if( r == 0 ) return 0; // no data if( r < 0 ){ Reset(5); return -1; } // error q = in_buffer.Count(); if( !q ){ int error = 0; socklen_t n = sizeof(error); if(getsockopt(m_sock, SOL_SOCKET,SO_ERROR,&error,&n) < 0 || error != 0 ){ CONSOLE.Warning(2, "warn, received nothing from CTCS: %s", strerror(error)); } Reset(0); return -1; } char *s, *msgbuf; while(in_buffer.Count() && (s=strchr(msgbuf=in_buffer.BasePointer(), '\n'))){ *s = '\0'; if(arg_verbose) CONSOLE.Debug("CTCS: %s", msgbuf); if( !strncmp("SETDLIMIT",msgbuf,9) ){ cfg_max_bandwidth_down = (int)(strtod(msgbuf+10, NULL)); if(arg_verbose) CONSOLE.Debug("DLimit=%d", cfg_max_bandwidth_down); }else if( !strncmp("SETULIMIT",msgbuf,9) ){ cfg_max_bandwidth_up = (int)(strtod(msgbuf+10, NULL)); if(arg_verbose) CONSOLE.Debug("ULimit=%d", cfg_max_bandwidth_up); }else if( !strncmp("SENDPEERS",msgbuf,9) ){ Send_Peers(); }else if( !strncmp("SENDSTATUS",msgbuf,10) ){ Send_Status(); }else if( !strncmp("SENDCONF",msgbuf,8) ){ Send_Config(); }else if( !strncmp("CTCONFIG",msgbuf,8) ){ Set_Config(msgbuf); }else if( !strncmp("SENDDETAIL",msgbuf,10) ){ Send_Detail(); }else if( !strncmp("CTQUIT",msgbuf,6) ){ CONSOLE.Print("CTCS sent Quit command"); Tracker.SetStoped(); }else if( !strncmp("CTRESTART",msgbuf,9) ){ RestartTracker(); }else if( !strncmp("CTUPDATE",msgbuf,8) ){ Tracker.Reset(1); }else if( !strncmp("PROTOCOL",msgbuf,8) ){ int proto = atoi(msgbuf+9); if( proto <= CTCS_PROTOCOL ) m_protocol = proto; else m_protocol = CTCS_PROTOCOL; }else{ if(arg_verbose) CONSOLE.Debug("unknown CTCS message: %s", msgbuf); } in_buffer.PickUp(s-msgbuf + 1); } m_last_timestamp = now; return 0;}int Ctcs::SendMessage(char *message){ int len, r=0; char buf[CTCS_BUFSIZE]; if( m_status == T_READY ){ len = strlen(message); strncpy(buf, message, len); if( len+1 < CTCS_BUFSIZE ){ buf[len] = '\n'; buf[len+1] = '\0'; }else{ buf[CTCS_BUFSIZE-2] = '\n'; buf[CTCS_BUFSIZE-1] = '\0'; } r = out_buffer.PutFlush(m_sock, buf, len+1); if( r<0 ) Reset(5); else m_last_timestamp = now; } return r;}int Ctcs::Send_Auth(){ char message[CTCS_BUFSIZE]; if(!*m_pass) return 0; snprintf(message, CTCS_BUFSIZE, "AUTH %s", m_pass); return SendMessage(message);}int Ctcs::Send_Protocol(){ char message[CTCS_BUFSIZE]; snprintf(message, CTCS_BUFSIZE, "PROTOCOL %04d", CTCS_PROTOCOL); return SendMessage(message);}int Ctcs::Send_Torrent(unsigned char *peerid, char *torrent){ char message[CTCS_BUFSIZE]; char txtid[PEER_ID_LEN*2+3]; TextPeerID(peerid, txtid); snprintf(message, CTCS_BUFSIZE, "CTORRENT %s %ld %ld %s", txtid, (long)(BTCONTENT.GetStartTime()), (long)now, torrent); return SendMessage(message);}int Ctcs::Report_Status(size_t seeders, size_t leechers, size_t nhave, size_t ntotal, size_t dlrate, size_t ulrate, uint64_t dltotal, uint64_t ultotal, size_t dlimit, size_t ulimit, size_t cacheused){ int changebw=0,change=0; int r; size_t nhad; if( T_READY != m_status ) return 0; nhad = m_ctstatus.nhave; changebw = ( compset(m_ctstatus, dlrate) | compset(m_ctstatus, ulrate) | compset(m_ctstatus, dlimit) | compset(m_ctstatus, ulimit) ); change = ( changebw | compset(m_ctstatus, seeders) | compset(m_ctstatus, leechers) | compset(m_ctstatus, nhave) | compset(m_ctstatus, ntotal) | compset(m_ctstatus, dltotal) | compset(m_ctstatus, ultotal) | compset(m_ctstatus, cacheused) ); if( ( !m_sent_ctstatus || (nhad<nhave && nhave==ntotal) || (Tracker.GetStatus() && now > m_sent_ctstatus_time+30) ) && (r=Send_Status()) != 0 ) return r; else return (changebw || !m_sent_ctbw) ? Send_bw() : 0;}int Ctcs::Send_Status(){ char message[CTCS_BUFSIZE]; if( m_sent_ctstatus_time + 1 > now ) { m_sent_ctstatus = 0; return 0; } if( m_protocol == 1 ) snprintf( message, CTCS_BUFSIZE, "CTSTATUS %d/%d %d/%d/%d %d,%d %llu,%llu %d,%d", (int)(m_ctstatus.seeders), (int)(m_ctstatus.leechers), (int)(m_ctstatus.nhave), (int)(m_ctstatus.ntotal), (int)(WORLD.Pieces_I_Can_Get()), (int)(m_ctstatus.dlrate), (int)(m_ctstatus.ulrate), (unsigned long long)(m_ctstatus.dltotal), (unsigned long long)(m_ctstatus.ultotal), (int)(m_ctstatus.dlimit), (int)(m_ctstatus.ulimit) ); else snprintf( message, CTCS_BUFSIZE, "CTSTATUS %d:%d/%d:%d/%d %d/%d/%d %d,%d %llu,%llu %d,%d %d", (int)(m_ctstatus.seeders), (int)(Tracker.GetSeedsCount() - ((BTCONTENT.pBF->IsFull() && Tracker.GetSeedsCount() > 0) ? 1 : 0)), (int)(m_ctstatus.leechers), (int)(Tracker.GetPeersCount() - Tracker.GetSeedsCount() - ((!BTCONTENT.pBF->IsFull() && Tracker.GetPeersCount() > 0) ? 1 : 0)), (int)(WORLD.GetConnCount()), (int)(m_ctstatus.nhave), (int)(m_ctstatus.ntotal), (int)(WORLD.Pieces_I_Can_Get()), (int)(m_ctstatus.dlrate), (int)(m_ctstatus.ulrate), (unsigned long long)(m_ctstatus.dltotal), (unsigned long long)(m_ctstatus.ultotal), (int)(m_ctstatus.dlimit), (int)(m_ctstatus.ulimit), (int)(m_ctstatus.cacheused) ); m_sent_ctstatus = 1; m_sent_ctstatus_time = now; return SendMessage(message);}int Ctcs::Send_bw(){ char message[CTCS_BUFSIZE]; snprintf(message, CTCS_BUFSIZE, "CTBW %d,%d %d,%d", (int)(m_ctstatus.dlrate), (int)(m_ctstatus.ulrate), (int)(m_ctstatus.dlimit), (int)(m_ctstatus.ulimit) ); m_sent_ctbw = 1; return SendMessage(message);}int Ctcs::Send_Config(){ char message[CTCS_BUFSIZE]; if( m_protocol == 1 ) snprintf(message, CTCS_BUFSIZE, "CTCONFIG %d %d %f %d %d %d %d %d %d", (int)arg_verbose, (int)cfg_seed_hours, cfg_seed_ratio, (int)cfg_max_peers, (int)cfg_min_peers, (int)arg_file_to_download, 0, WORLD.IsPaused(), 0); else
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -