void Sender::startSending() { std::thread SendThread( [&]() { do { try { IMessage *msg = sendQ.deQ(); /*Message* msg = dynamic_cast<Message*>(imsg); map<string, string> header = msg->getHeader();*/ if (msg->getCommand() == "send_stop") break; else if (msg->getCommand() == "file_upload") { if (connectToPeer(msg->getRecvIP(), stoi(msg->getRecvPort()))) { if (sendFile(msg)) { } } else Verbose::show("Connection failed!\n"); } else if (msg->getCommand() == "ack") { if (connectToPeer(msg->getRecvIP(), stoi(msg->getRecvPort()))) sendHeader(msg); } else { if (connectToPeer(msg->getRecvIP(), stoi(msg->getRecvPort()))) { sendHeader(msg); sendBody(msg); } } } catch (exception ex) { string s = ex.what(); Verbose::show("\n In send Thread: " + s); } } while (1); } ); SendThread.detach(); }
int parseTrackerResponse( struct torrentInfo * torrent, char * response, int responseLen ) { int i,j; // Find the number of bytes designated to peers char * peerListPtr = strstr( response, "5:peers" ); if ( ! peerListPtr ) { return 0; } peerListPtr += strlen( "5:peers" ); char * numEnd = peerListPtr; while ( (*numEnd) && (*(numEnd) != ':') ) { numEnd ++ ; } *numEnd = '\0'; int numBytes = atoi( peerListPtr ); logToFile( torrent, "TRACKER RESPONSE Number of Peers: %d\n", numBytes / 6 ); *numEnd = ':'; if ( response + responseLen < numEnd+1+numBytes ) { // We still need more data ... return 0; } char * intervalPtr = strstr( response, "8:intervali" ); if ( ! intervalPtr ) { return 0; } char * intervalPtrStart = intervalPtr + strlen( "8:intervali" ); char * intervalPtrEnd = strchr( intervalPtrStart, 'e' ); if ( ! intervalPtrEnd ) { return 0; } *intervalPtrEnd = '\0'; int interval = atoi( intervalPtrStart ); *intervalPtrEnd = 'e'; unsigned char ip[4]; uint16_t portBytes; peerListPtr = numEnd + 1; char handshake[68]; char tmp = 19; memcpy( &handshake[0], &tmp, 1 ); char protocol[20]; strncpy( protocol, "BitTorrent protocol", 19 ); memcpy( &handshake[1], protocol, 19 ); int flags = 0; memcpy( &handshake[20], &flags, 4 ); memcpy( &handshake[24], &flags, 4 ); memcpy( &handshake[28], torrent->infoHash, 20 ); memcpy( &handshake[48], torrent->peerID, 20 ); #ifdef TRACKER_RESP_HACK // Overwrite the first peer with a particular IP and port if ( numBytes / 6 > 0 ) { char fake[6]; char * ptr = fake; char fake1 = IP0; memcpy( ptr, &fake1, 1 ); fake1 = IP1; memcpy( ptr+1, &fake1, 1 ); fake1 = IP2; memcpy( ptr+2, &fake1, 1 ); fake1 = IP3; memcpy( ptr+3, &fake1, 1 ); short fakePort = htons( PORT ); memcpy( ptr+4, &fakePort, 2 ); memcpy( peerListPtr, ptr, 6 ); } #endif for ( i = 0; i < numBytes/6; i ++ ) { int newSlot = getFreeSlot( torrent ); struct peerInfo * this = &torrent->peerList[ newSlot ]; // Get IP and port data in the right place memcpy( ip, peerListPtr, 4 ); memcpy( &portBytes, peerListPtr + 4, 2 ); snprintf( this->ipString, 16, "%u.%u.%u.%u", (int)ip[0], (int)ip[1], (int)ip[2], (int)ip[3] ); this->portNum = ntohs( portBytes ); // Before continuing, see if we already have an existing // connection with this host int exists = 0; for( j = 0; j < torrent->peerListLen; j ++ ) { if ( j == newSlot || torrent->peerList[j].defined == 0 ) { continue; } if ( !strcmp( torrent->peerList[j].ipString, this->ipString ) ) { exists = 1; break; } } if ( exists ) { this->defined = 0; break; } if ( connectToPeer( this, torrent, handshake ) ) { logToFile( torrent, "STATUS Initializing %s:%u - FAILED\n", this->ipString, (int)this->portNum ); } else { logToFile( torrent, "STATUS Initializing %s:%u - SUCCESS\n", this->ipString, (int)this->portNum ); } peerListPtr += 6; } return interval; }
result_type Peer::whenCredentialsAreProvided(const descriptor_pair & sourceDesc, peer_id sourceId) { result_type res = SUCCESS; address otherAddr; peer_id targetId; std::string targetIp; res = recv_(coordinatorFd, 0, targetIp); if (targetIp.length() == 0) { TEST() std::cout << "peer is not yet registered" << std::endl; establishNextConnectionIfAvailable(); return NOTHING; } if (targetIp == "local") { TEST() std::cout << "peer is in the local network" << std::endl; res = recv_(coordinatorFd, 0, targetIp); // get public IP, in case local connection fails and its needed otherAddr.ip = this->localIp; } else { otherAddr.ip = targetIp; } res = recv_(coordinatorFd, 0, otherAddr.port); res = recv_(coordinatorFd, 0, targetId); QUIT_IF_UNSUCCESSFUL(res); TEST() std::cout << "received creds " << targetId << " " << otherAddr << " (public IP: " << targetIp << ")"<< std::endl; TEST() std::cout << "connecting using sockets" << std::endl; int fd = connectToPeer(otherAddr, false); // connect (here, otherAddr can be a local or public IP) if (fd == -1 and otherAddr.ip == localIp) { // failed when connecting locally TEST() std::cout << "local connection failed. trying public IP" << std::endl; otherAddr.ip == targetIp; fd = connectToPeer(otherAddr, false); } if (fd == -1) { #ifndef DISABLE_LIBNICE res = requestNiceConnectionTo(targetId); #else res = requestRelayedConnectionTo(targetId); #endif return res; } TEST() std::cout << "connected" << std::endl; res = send_type_(fd, REGISTER); res = send_(fd, this->ownId); QUIT_IF_UNSUCCESSFUL(res); peer_id arguedId; res = recv_(fd, 0, arguedId); QUIT_IF_UNSUCCESSFUL(res); if (arguedId != targetId) { return FAILURE; } TEST() std::cout << "registered with peer" << std::endl; setNewPeerStructures(fd, targetId, DESCRIPTOR_SOCK); std::cout << knownPeers.toString() << std::endl; TEST() std::cout << "end establishConnection" << std::endl; establishNextConnectionIfAvailable(); return res; }
int ClientFileTransmissionPacketsParser::connectToServer(){ IMUser *myself = IMUser::instance(); m_socketConnectedToServer = connectToPeer(QHostAddress(myself->getFileServerAddress()), myself->getFileServerPort()); return m_socketConnectedToServer; }
result_type Peer::registerWithCoordinator() { result_type res; coordinatorFd = connectToPeer(coordinatorAddr, true); res = send_type_(coordinatorFd, REGISTER); QUIT_IF_UNSUCCESSFUL(res); res = recv_(coordinatorFd, 0, ownId); // receive registration ID QUIT_IF_UNSUCCESSFUL(res); std::cout << "ID: " << this->ownId << std::endl; setNewPeerStructures(coordinatorFd, 0, DESCRIPTOR_SOCK); // the coordinator has always ID = 0 res = recv_(coordinatorFd, 0, nPeers); QUIT_IF_UNSUCCESSFUL(res); this->usingFreeformLayout = (nPeers == 0); if (!this->usingFreeformLayout) { // receive all peers that are upstream or downstream of this peer_id * prev = NULL, * next = NULL; uint prevSize = 0, nextSize = 0; res = recv_new_(coordinatorFd, 0, prev, prevSize); QUIT_IF_UNSUCCESSFUL(res); res = recv_new_(coordinatorFd, 0, next, nextSize); QUIT_IF_UNSUCCESSFUL(res); printIds(prev, prevSize, "previous"); printIds(next, nextSize, "next"); this->prevPeers.assign(prev+0, prev+prevSize); this->nextPeers.assign(next+0, next+nextSize); free(prev); free(next); } // receive which next/prev IDs are already registered peer_id * connectable_array; uint connectableSize = 0; res = recv_new_(coordinatorFd, 0, connectable_array, connectableSize); QUIT_IF_UNSUCCESSFUL(res); connectable.insert(connectable_array+0, connectable_array+connectableSize); if (this->usingFreeformLayout) { this->nextPeers.assign(connectable.begin(), connectable.end()); // when there's no layout, all connectable peers are considered to be "next" } free(connectable_array); TEST() { std::cout << "connectable peers:" << std::endl; for (peer_id id : connectable) std::cout << "id: " << id << std::endl; std::cout << "---------------------" << std::endl; } return res; }