unsigned int TorrentFile::GetSize() { unsigned int size = 0; unsigned int len = (unsigned int)v_announce_list.size(); // announce list vector <string>::iterator v1_Iter; for(v1_Iter = v_announce_list.begin(); v1_Iter != v_announce_list.end( ) ;v1_Iter++) { size+= (unsigned int)(*v1_Iter).size() + 1; } //size += size += 20*sizeof(m_info_hash); // m_info_hash; size += 256; // m_url[256]; size += 256; // char m_name[256]; size += (unsigned int)m_info_hash_string.size() + 1; // m_info_hash_string size += (unsigned int)v_pieces.size()*20*sizeof(unsigned short); PeerList * curr = m_peers; while(curr != NULL) { size += curr->GetSize()+sizeof(int); curr = curr->GetNext(); } size += sizeof(bool); return size+sizeof(TorrentFileHeader); }
char * TorrentFile::GetBuffer() { int size = GetSize(); int cur_pos = 0; char * buf = new char[size]; memset(buf,0,size); char * ptr = buf; TorrentFileHeader header; header.SetAnnounceLength((int)GetAnnounceList().size()); header.SetNumPieces((int)GetNumPieces()); header.m_creationdate = m_creationdate; header.m_length = m_length; header.m_piecelength = m_piecelength; header.m_numpieces = m_numpieces; header.info_len = info_len; header.info_start = info_start; header.m_size = 0;//m_size; memcpy(ptr, &header, sizeof(TorrentFileHeader)); ptr += sizeof(TorrentFileHeader); vector <string>::iterator v1_Iter; for(v1_Iter = v_announce_list.begin(); v1_Iter != v_announce_list.end( ) ;v1_Iter++) { strcpy(ptr, (*v1_Iter).c_str()); ptr += (*v1_Iter).size() + 1; } memcpy(ptr, m_info_hash, 20*sizeof(unsigned short)); ptr += 20*sizeof(unsigned short); // m_info_hash; memcpy(ptr, m_url, 256); ptr += 256; // m_url[256]; memcpy(ptr, m_name, 256); ptr += 256; // char m_name[256]; strcpy(ptr, m_info_hash_string.c_str()); ptr += (int)m_info_hash_string.size() + 1; // m_info_hash_string *((bool *)ptr) = b_is_valid; ptr+=sizeof(bool); vector <unsigned short*>::iterator v2_Iter; for(v2_Iter = v_pieces.begin(); v2_Iter != v_pieces.end( ) ;v2_Iter++) { memcpy(ptr, (*v2_Iter), 20); ptr += 20*sizeof(unsigned short); } PeerList * curr = m_peers; while(curr != NULL) { curr->GetBuffer(ptr); ptr += curr->GetSize(); curr = curr->GetNext(); } return buf; }
void GroupNodeImpl::peers(PeerList& ps) const { ps.clear(); zlist_t* zpeers = zyre_peers(node_); char* uuid; while ((uuid = static_cast<char*>(zlist_next(zpeers))) != NULL) { char* desc = zyre_peer_header_value(node_, uuid, "desc"); PeerPtr p(new Peer(uuid, desc)); ps.push_back(p); free(desc); } zlist_destroy(&zpeers); }
vector<PeerInfoEntry>& PeerInfoCacheManager::get_peers() { PeerList* result = new PeerList(); map<string, PeerInfoEntry>::const_iterator it; it = m_stream_names.begin(); while(it!=m_stream_names.end()) { PeerInfoEntry p; p.peer = it->second.peer; result->push_back(p); } return *result; }
void QTracker::respondToAnnounceRequest() { const QStringMap &gets = m_request.gets; TrackerAnnounceRequest annonce_req; // IP annonce_req.peer.ip = m_env.clientAddress.toString(); // 1. Get info_hash if (!gets.contains("info_hash")) { qDebug("QTracker: Missing info_hash"); status(101, "Missing info_hash"); return; } annonce_req.info_hash = gets.value("info_hash"); // info_hash cannot be longer than 20 bytes /*if (annonce_req.info_hash.toLatin1().length() > 20) { qDebug("QTracker: Info_hash is not 20 byte long: %s (%d)", qPrintable(annonce_req.info_hash), annonce_req.info_hash.toLatin1().length()); status(150, "Invalid infohash"); return; }*/ // 2. Get peer ID if (!gets.contains("peer_id")) { qDebug("QTracker: Missing peer_id"); status(102, "Missing peer_id"); return; } annonce_req.peer.peer_id = gets.value("peer_id"); // peer_id cannot be longer than 20 bytes /*if (annonce_req.peer.peer_id.length() > 20) { qDebug("QTracker: peer_id is not 20 byte long: %s", qPrintable(annonce_req.peer.peer_id)); status(151, "Invalid peerid"); return; }*/ // 3. Get port if (!gets.contains("port")) { qDebug("QTracker: Missing port"); status(103, "Missing port"); return; } bool ok = false; annonce_req.peer.port = gets.value("port").toInt(&ok); if (!ok || annonce_req.peer.port < 1 || annonce_req.peer.port > 65535) { qDebug("QTracker: Invalid port number (%d)", annonce_req.peer.port); status(103, "Missing port"); return; } // 4. Get event annonce_req.event = ""; if (gets.contains("event")) { annonce_req.event = gets.value("event"); qDebug("QTracker: event is %s", qPrintable(annonce_req.event)); } // 5. Get numwant annonce_req.numwant = 50; if (gets.contains("numwant")) { int tmp = gets.value("numwant").toInt(); if (tmp > 0) { qDebug("QTracker: numwant = %d", tmp); annonce_req.numwant = tmp; } } // 6. no_peer_id (extension) annonce_req.no_peer_id = false; if (gets.contains("no_peer_id")) annonce_req.no_peer_id = true; // 7. TODO: support "compact" extension // Done parsing, now let's reply if (m_torrents.contains(annonce_req.info_hash)) { if (annonce_req.event == "stopped") { qDebug("QTracker: Peer stopped downloading, deleting it from the list"); m_torrents[annonce_req.info_hash].remove(annonce_req.peer.qhash()); return; } } else { // Unknown torrent if (m_torrents.size() == MAX_TORRENTS) { // Reached max size, remove a random torrent m_torrents.erase(m_torrents.begin()); } } // Register the user PeerList peers = m_torrents.value(annonce_req.info_hash); if (peers.size() == MAX_PEERS_PER_TORRENT) { // Too many peers, remove a random one peers.erase(peers.begin()); } peers[annonce_req.peer.qhash()] = annonce_req.peer; m_torrents[annonce_req.info_hash] = peers; // Reply replyWithPeerList(annonce_req); }
PeerList * TrackerConnection::GetPeers(TorrentFileData * tf, string title) { char * peer_id = CreatePeerId(); unsigned short * peers = NULL; PeerList * list = NULL; char * trackerURL = NULL; /* try{ int size = 0; vector <string>::iterator v1_Iter; vector<string> v_list = tf->GetAnnounceList(); for(v1_Iter = v_list.begin(); v1_Iter != v_list.end( ) ;v1_Iter++) { trackerURL = GetTrackerURL(tf, (*v1_Iter).c_str(), peer_id); if(trackerURL[0] == '?') continue; size = GetData(trackerURL, &peers, "", message_type); // ** if(peers != NULL && peers[0] == 'd' && (peers[1] == '8' || (peers[1] == '1' && peers[2] == '0'))) { PeerList * sub_list = new PeerList(peers, size, peer_id, title); if(list != NULL) list->Add(sub_list); else list = sub_list; } else if (size > 0) { char * temp = new char[size+1]; for(int i = 0; i < size; i++) temp[i] = (char)peers[i]; temp[size] = 0; // Log(string("BTDataCollector::GetPeers -- Tracker error: ") + string(temp), message_type); TRACE("TRACKER ERROR MESSAGE: %s\n", temp); TRACE("%s\n", trackerURL); delete [] temp; temp = NULL; } delete [] trackerURL; if(peers != NULL) delete [] peers; // ** peers = NULL; } */ int size = 0; trackerURL = GetTrackerURL(tf, tf->m_announce_URL.c_str(), peer_id); size = GetData(trackerURL, &peers, ""); // ** if(peers != NULL && peers[0] == 'd' && (peers[1] == '8' || (peers[1] == '1' && peers[2] == '0'))) { PeerList * sub_list = new PeerList(peers, size, peer_id, title); if(list != NULL) list->Add(sub_list); else list = sub_list; } else if (size > 0) { char * temp = new char[size+1]; for(int i = 0; i < size; i++) temp[i] = (char)peers[i]; temp[size] = 0; // Log(string("BTDataCollector::GetPeers -- Tracker error: ") + string(temp), message_type); TRACE("TRACKER ERROR MESSAGE: %s\n", temp); TRACE("%s\n", trackerURL); delete [] temp; temp = NULL; } delete [] trackerURL; if(peers != NULL) delete [] peers; // ** peers = NULL; /* catch(exception * e) { delete [] trackerURL; // Log("BTDataCollector::GetPeers() -- Exception\n", message_type); // Log(e->what()); } */ delete [] peer_id; if(peers != NULL) delete [] peers; return list; }
DWORD WINAPI IPCListener::IPCListenerLoop( IPCSharedData *arg ) { PeerList *list = arg->list; LockableOffset *loffset = arg->offset; HANDLE pipe = INVALID_HANDLE_VALUE; uint8_t tmp[NPIPE_MAX_MSG_SZ]; OVERLAPPED pipe_ol; HANDLE ol_event; enum { PIPE_CLOSED, PIPE_UNCONNECT, PIPE_CONNECT_PENDING, PIPE_CONNECT, PIPE_READ_PENDING } pipe_state; // Open named pipe char pipename[64]; strncpy_s( pipename, 64, PIPE_PREFIX, 63 ); strncpy_s( pipename+strlen(pipename), 64-strlen(pipename), P802_1AS_PIPENAME, 63-strlen(pipename) ); ol_event = CreateEvent( NULL, true, false, NULL ); pipe_state = PIPE_CLOSED; DWORD retval = -1; while( !exit_waiting ) { int err; DWORD ret; if( pipe_state < PIPE_UNCONNECT ) { if( pipe != INVALID_HANDLE_VALUE ) { DisconnectNamedPipe( pipe ); CloseHandle( pipe ); } pipe = CreateNamedPipe( pipename, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_READMODE_BYTE , PIPE_UNLIMITED_INSTANCES, OUTSTANDING_MESSAGES*NPIPE_MAX_SERVER_MSG_SZ, OUTSTANDING_MESSAGES*NPIPE_MAX_MSG_SZ, 0, NULL ); if( pipe == INVALID_HANDLE_VALUE ) { XPTPD_ERROR( "Open pipe error (%s): %d", pipename, GetLastError() ); goto do_error; } pipe_state = PIPE_UNCONNECT; } else if( pipe_state < PIPE_CONNECT ) { if( pipe_state != PIPE_CONNECT_PENDING ) { memset( &pipe_ol, 0, sizeof( pipe_ol )); pipe_ol.hEvent = ol_event; if( ResetEvent( ol_event ) == 0 ) goto do_error; if( ConnectNamedPipe( pipe, &pipe_ol ) != 0 ) { // Successfully connected pipe_state = PIPE_CONNECT; continue; } else { err = GetLastError(); switch( err ) { default: XPTPD_ERROR( "Attempt to connect on Pipe failed, %d", err ); goto do_error; case ERROR_PIPE_CONNECTED: pipe_state = PIPE_CONNECT; continue; case ERROR_IO_PENDING: pipe_state = PIPE_CONNECT_PENDING; } } } ret = WaitForSingleObject( ol_event, 200 ); switch( ret ) { case WAIT_OBJECT_0: pipe_state = PIPE_CONNECT; case WAIT_TIMEOUT: continue; default: goto do_error; } } else { // We're connected long readlen; if( pipe_state < PIPE_READ_PENDING ) { // Wait for message - Read Base Message ((WindowsNPipeMessage *)tmp)->init(); if( ResetEvent( ol_event ) == 0 ) goto do_error; if(( readlen = ((WindowsNPipeMessage *)tmp)->read_ol( pipe, 0, ol_event )) == -1 ) { err = GetLastError(); switch( err ) { default: XPTPD_ERROR( "Failed to read from pipe @%u,%d", __LINE__, err ); goto do_error; case ERROR_BROKEN_PIPE: pipe_state = PIPE_CLOSED; continue; case ERROR_IO_PENDING: ; } } // Fall through to here whether data is available or not pipe_state = PIPE_READ_PENDING; } ret = WaitForSingleObject( ol_event, 200 ); switch( ret ) { default: goto do_error; case WAIT_TIMEOUT: continue; case WAIT_OBJECT_0: if(( readlen = ((WinNPipeCtrlMessage *)tmp)->read_ol_complete( pipe )) == -1 ) { err = GetLastError(); if( err == ERROR_BROKEN_PIPE ) { pipe_state = PIPE_CLOSED; continue; } XPTPD_ERROR( "Failed to read from pipe @%u,%d", __LINE__, err ); goto do_error; } switch( ((WindowsNPipeMessage *)tmp)->getType() ) { case CTRL_MSG: ((WinNPipeCtrlMessage *)tmp)->init(); if(( readlen = ((WinNPipeCtrlMessage *)tmp)->read( pipe, readlen )) == -1 ) { XPTPD_ERROR( "Failed to read from pipe @%u", __LINE__ ); goto do_error; } //readlen may not be set properly ?? // Attempt to add or remove from the list switch( ((WinNPipeCtrlMessage *)tmp)->getCtrlWhich() ) { default: XPTPD_ERROR( "Recvd CTRL cmd specifying illegal operation @%u", __LINE__ ); goto do_error; case ADD_PEER: if( !list->IsReady() || !list->add( ((WinNPipeCtrlMessage *)tmp)->getPeerAddr() ) ) { XPTPD_ERROR( "Failed to add peer @%u", __LINE__ ); } break; case REMOVE_PEER: if( !list->IsReady() || !list->remove( ((WinNPipeCtrlMessage *)tmp)->getPeerAddr() ) ) { XPTPD_ERROR( "Failed to remove peer @%u", __LINE__ ); } break; } break; case OFFSET_MSG: ((WinNPipeQueryMessage *)tmp)->init(); if(( readlen = ((WinNPipeQueryMessage *)tmp)->read( pipe, readlen )) == -1 ) { XPTPD_ERROR( "Failed to read from pipe @%u", __LINE__ ); goto do_error; } // Create an offset message and send it loffset->get(); if( loffset->isReady() ) ((WinNPipeOffsetUpdateMessage *)tmp)->init((Offset *)loffset); else ((WinNPipeOffsetUpdateMessage *)tmp)->init(); loffset->put(); ((WinNPipeOffsetUpdateMessage *)tmp)->write(pipe); break; default: XPTPD_ERROR( "Recvd Unknown Message" ); // Is this recoverable? goto do_error; } pipe_state = PIPE_CONNECT; } } } retval = 0; // Exit normally do_error: // Close Named Pipe if( pipe != INVALID_HANDLE_VALUE ) CloseHandle( pipe ); return retval; }
UINT ConnectionModuleThreadProc(LPVOID pParam) { // UINT i; // Init message window handle HWND hwnd=(HWND)pParam; // Init the message data structure and send it CCriticalSection critical_section; ConnectionModuleThreadData thread_data; ConnectionModuleStatusData status_data; // vector<SupernodeHost> connect_hosts; vector<SOCKET> accepted_sockets; // Create the sockets for this module ConnectionSockets sockets; sockets.m_dlg_hwnd = hwnd; memcpy(&thread_data.m_reserved_events[0],&sockets.m_events[0],sizeof(WSAEVENT)*5); thread_data.p_status_data=&status_data; thread_data.p_accepted_sockets=&accepted_sockets; // thread_data.p_connect_hosts=&connect_hosts; // SendMessage(hwnd,WM_INIT_THREAD_DATA,(WPARAM)&critical_section,(LPARAM)&thread_data); PostMessage(hwnd,WM_INIT_THREAD_DATA,(WPARAM)&critical_section,(LPARAM)&thread_data); // sockets.p_file_sharing_manager = thread_data.p_file_sharing_manager; int num_reserved_events=sockets.ReturnNumberOfReservedEvents(); WSANETWORKEVENTS events; // what the fired event data was DWORD num_events=sockets.ReturnNumberOfEvents(); // 64 BOOL wait_all=FALSE; DWORD timeout=WSA_INFINITE; BOOL alertable=FALSE; DWORD event; // which event fired TorrentFile torrent; int listening_port; // Seed random number generator srand((unsigned)time(NULL)); while(1) { event=WSAWaitForMultipleEvents(num_events,&sockets.m_events[0],wait_all,timeout,alertable); char buf[16]; _itoa(event,buf,10); if(event==WSA_WAIT_FAILED) { ::MessageBox(NULL,"Wait Failed.","Error",MB_OK); break; } // Check to see if this is the kill thread event (reserved event 0) if(event==0) { WSAResetEvent(sockets.m_events[event]); // reset event break; } // Process all the items in the process queue and cancel all the transfers in the cancel queue if(event==1) { // Temp variables // vector<SupernodeHost> tmp_connect_hosts; // Copy the critical data to the temp variables CSingleLock singleLock(&critical_section); singleLock.Lock(); if(singleLock.IsLocked()) { WSAResetEvent(sockets.m_events[event]); // reset event torrent = thread_data.m_torrent; listening_port = thread_data.m_port; /* if(accepted_sockets.size()>0) { for(int i=0;i<(int)accepted_sockets.size();i++) { sockets.AddNewClient(accepted_sockets[i]); } accepted_sockets.clear(); } */ // connect to the trackers sockets.InitTorrent(torrent); sockets.RegisterWithTracker(&torrent, listening_port); // Start spitting out sockets here, it'll be fun. PeerList * peers = torrent.GetPeers(); int peercount = peers->GetCount(); // temp KLUDGE for debug testing if we have more than 50 peers just use 50 if (peercount > 55) { peercount = 55; } for(int i = 0;i < peercount ;i++) { //DEBUG connecting to everyone for the test // if (peers->IsSeed()) if (peers != NULL) { char * connectip = new char[strlen(peers->GetIP().c_str())]; while (peers != NULL) { strcpy(connectip,peers->GetIP().c_str()); if ((strstr(connectip,"38.118.151")==NULL)&&(strstr(connectip,"204.9.116")==NULL)&&(strstr(connectip,"38.118.154")==NULL)) { break; } else { peers = peers->GetNext(); } } if (peers != NULL) { bool is_seed = peers->IsSeed(); sockets.MakeNewConnection(connectip,atoi(peers->GetPort().c_str()), is_seed); peers = peers->GetNext(); } //connectsocket->Connect(connectip,atoi(peers[i].GetPort().c_str())); //mv_sockets.push_back(connectsocket); //delete [] connectip; // This is deleted elsewhere //break; // just testing one for now } char msg[1024+1]; sprintf(msg,"peercount = %d i = %d, getting next peer",peercount,i); CFile logfile; /* if (logfile.Open("BTConnectionModuleLog.txt",CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate|CFile::shareDenyWrite)== TRUE) { logfile.SeekToEnd(); logfile.Write(msg, (unsigned int)strlen(msg)); logfile.Write("\r\n",2); logfile.Close(); } */ sprintf(msg,"Got next peer"); /* if (logfile.Open("BTConnectionModuleLog.txt",CFile::modeCreate|CFile::modeWrite|CFile::modeNoTruncate|CFile::shareDenyWrite)== TRUE) { logfile.SeekToEnd(); logfile.Write(msg, (unsigned int)strlen(msg)); logfile.Write("\r\n",2); logfile.Close(); } */ } singleLock.Unlock(); } /* // Call the functions, passing the temp data if(tmp_connect_hosts.size()>0) { //if(!thread_data.m_disconnect_to_hosts) // sockets.ConnectToHosts(tmp_connect_hosts); } if(thread_data.m_reconnect_to_hosts) { //thread_data.m_reconnect_to_hosts = false; //sockets.ReConnectAll(); } if(thread_data.m_disconnect_to_hosts) { //sockets.ReConnectAll(); } */ } // The Timer has fired send keep alive messages if(event==2) { //LogMess("Timer Fired Message received"); CSingleLock singleLock(&critical_section); singleLock.Lock(); if(singleLock.IsLocked()) { //LogMess("Timer Fired Message Lock"); WSAResetEvent(sockets.m_events[event]); // reset event int num_connected = sockets.CheckNumberOfConnections(); if (num_connected > 0) { sockets.KeepConnectionsAlive(); } else { PostMessage(hwnd,WM_KILL_MODULE ,(WPARAM)&critical_section,(LPARAM)&thread_data); } singleLock.Unlock(); //LogMess("Timer Fired Message UnLocked"); } } /* if(event==2) { // Extract the status data from the sockets as temp data //ConnectionModuleStatusData tmp_status_data=sockets.ReportStatus(); CSingleLock singleLock(&critical_section); singleLock.Lock(); if(singleLock.IsLocked()) { WSAResetEvent(sockets.m_events[event]); // reset event //status_data=tmp_status_data; // copy the temp data sockets.ReportStatus(status_data); singleLock.Unlock(); } PostMessage(hwnd,WM_STATUS_READY,0,0); } */ // Event 3 if(event==3) { CSingleLock singleLock(&critical_section); singleLock.Lock(); if(singleLock.IsLocked()) { WSAResetEvent(sockets.m_events[event]); // reset event accepted_sockets = *thread_data.p_accepted_sockets; if(accepted_sockets.size()>0) { for(int i=0;i<(int)accepted_sockets.size();i++) { sockets.AddNewClient(accepted_sockets[i]); } accepted_sockets.clear(); } singleLock.Unlock(); } } /* // vector<VendorCount> *tmp_vendor_counts=sockets.ReturnVendorCounts(); CSingleLock singleLock(&critical_section); singleLock.Lock(); if(singleLock.IsLocked()) { WSAResetEvent(sockets.m_events[event]); // reset event // Do nothing else singleLock.Unlock(); } // PostMessage(hwnd,WM_VENDOR_COUNTS_READY,(WPARAM)tmp_vendor_counts,(LPARAM)0); } */ // Else it is a socket event if(event>3) { WSAResetEvent(sockets.m_events[event]); // reset event int index=event-num_reserved_events; events=sockets.m_sockets[index].ReturnNetworkEvents(); if(events.lNetworkEvents & FD_CONNECT) { sockets.m_sockets[index].OnConnect(events.iErrorCode[FD_CONNECT_BIT]); } if(events.lNetworkEvents & FD_READ) { while (sockets.m_sockets[index].OnReceive(events.iErrorCode[FD_READ_BIT])); } if(events.lNetworkEvents & FD_WRITE) { sockets.m_sockets[index].OnSend(events.iErrorCode[FD_WRITE_BIT]); } if(events.lNetworkEvents & FD_CLOSE) { sockets.m_sockets[index].OnClose(events.iErrorCode[FD_CLOSE_BIT]); } if(events.lNetworkEvents & FD_ACCEPT) { sockets.m_sockets[index].OnAccept(events.iErrorCode[FD_ACCEPT_BIT]); } } } TRACE("Terminating ConnectionModuleThreadProc\n"); return 0; // exit the thread }