last commit

master
Thies Block 12 months ago
parent f80993fed3
commit 239efa6f44
Signed by: thiesyy
GPG Key ID: 3344988F036E9390
  1. 3
      .vscode/settings.json
  2. 44
      inc/fileutility.hpp
  3. 84
      inc/packetmanager.hpp
  4. 4
      inc/protocol.hpp
  5. 32
      inc/trackserver.hpp
  6. 6
      inc/udpclient.hpp
  7. 56
      src/fileutility.cpp
  8. 128
      src/main.cpp
  9. 261
      src/packetmanager.cpp
  10. 8
      src/settings.cpp
  11. 77
      src/trackserver.cpp
  12. 78
      src/udpclient.cpp
  13. 12
      src/udpserver.cpp

@ -50,6 +50,7 @@
"stdexcept": "cpp",
"streambuf": "cpp",
"cinttypes": "cpp",
"typeinfo": "cpp"
"typeinfo": "cpp",
"cstring": "cpp"
}
}

@ -6,18 +6,17 @@
#include "settings.hpp"
class File;
class FileUtility;
class FileUtility {
class IncompleteFile {
public:
static std::vector<File> files;
static void prepfile(const std::string& filepath);
static File getFile(const std::string& hash);
static std::string hashblock(char* data, uint64_t size);
private:
static std::string hashfile(const std::string& filepath, uint64_t* filesize);
static std::string sha256_hash_string(
unsigned char hash[SHA256_DIGEST_LENGTH]);
IncompleteFile(const std::string& filename,
const std::string& hash,
const uint64_t& filesize,
const uint64_t chunks);
std::vector<uint64_t> chunksset;
std::string filename;
std::string hash;
uint64_t filesize;
uint64_t chunks;
};
class File {
public:
@ -28,7 +27,30 @@ class File {
std::string filename;
std::string hash;
uint64_t filesize;
};
class FileUtility {
public:
static std::vector<File> files;
static std::vector<IncompleteFile*> incompletefiles;
~FileUtility();
static void prepfile(const std::string& filepath);
static File getFile(const std::string& hash);
static File getFileByName(const std::string& name);
static std::string hashblock(char* data, uint64_t size);
static void createWithSize(const std::string& filename, uint64_t size);
static void copyData(const std::string& filename,
uint64_t p,
char* data,
uint64_t size);
static std::string hashfile(const std::string& filepath, uint64_t* filesize);
static IncompleteFile* getIncompleteFile(const std::string& hash);
private:
static std::string sha256_hash_string(
unsigned char hash[SHA256_DIGEST_LENGTH]);
};
#endif

@ -2,29 +2,85 @@
#ifndef packetmanager_hpp
#define packetmanager_hpp
#include <stdint.h>
#include <cstring>
#include "protocol.hpp"
#pragma pack(push, 1)
struct Packet {
char identifier = p_identifier_req;
uint8_t pid = p_p_err;
char file_hash[64] = "";
Packet() {
identifier = p_identifier_req;
pid = p_p_err;
memset(file_hash, 0, sizeof(file_hash));
}
char identifier;
char pid;
char file_hash[65];
};
struct FileInfoPacket : Packet {
char filename[256] = "";
uint8_t pid = p_p_info;
uint64_t filesize = 0;
struct FileInfoPacket : public Packet {
FileInfoPacket() {
pid = p_p_info;
memset(filename, 0, sizeof(filename));
filesize = 0;
}
char filename[256];
uint64_t filesize;
};
struct FileDataPacket : Packet {
char data[blocksize] = "";
uint8_t pid = p_p_block;
uint32_t chunkid = 0;
char data_hash[65] = "";
struct FileDataRequestPacket : public Packet {
FileDataRequestPacket() {
pid = p_p_block;
chunkid = 0;
}
uint32_t chunkid;
};
struct FileDataPacket : public Packet {
FileDataPacket() {
pid = p_p_block;
memset(data, 0, sizeof(data));
memset(data_hash, 0, sizeof(data_hash));
chunkid = 0;
datasize = 0;
}
uint16_t datasize;
char data[blocksize];
uint32_t chunkid;
char data_hash[65];
};
#pragma pack(pop)
class PacketManager {
public:
PacketManager();
void manageData(int fd, char* data, unsigned long size, void* client);
void handlePacket_request(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic);
void handlePacket_data(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic);
void handlePacket_req_info(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic);
void handlePacket_req_data(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic);
void handlePacket_data_info(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic);
void handlePacket_data_data(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic);
void sendError(int fd, char* data, unsigned long& size, void* client);
private:
};

@ -1,8 +1,8 @@
#ifndef protocol_hpp
#define protocol_hpp
#define DEF_TRACKER_PORT 8126
#define DEF_PORT 8122
#define p_headersize 16
#define blocksize 65536
#define blocksize 49152
#define p_identifier_req '#'
#define p_identifier_send '!'
#define p_p_err '0'

@ -0,0 +1,32 @@
#ifndef trackserver_hpp
#define trackserver_hpp
#include <cstring>
#include <iostream>
#include <vector>
struct TrackerPacket {
int portn;
char searching;
char hash[65];
char addr[32];
TrackerPacket() {
memset(addr, 0, sizeof(addr));
memset(hash, 0, sizeof(hash));
searching = 'n';
portn = 0;
};
};
class TrackServer {
public:
std::string addr;
int port;
};
class TrackServerManager {
public:
std::vector<TrackServer> trackers;
void addTracker(const std::string& addr, int port);
void AnnounceHash(const std::string hash);
int connectTo(TrackServer ts);
std::string AskHash(const std::string hash);
};
#endif

@ -7,11 +7,15 @@ class UDPClient {
public:
UDPClient(const std::string& addr, int port);
UDPClient(const std::string& addr);
~UDPClient();
void requestInfo(const std::string& hash);
void requestChunk(const std::string& hash, uint64_t chunk);
void setdata(const std::string& addr, int port);
void setdata(const std::string& addr);
private:
void createSocket();
PacketManager* pmgr;
std::string addr;
int port;
int clientsocket;

@ -1,10 +1,21 @@
#include "fileutility.hpp"
#include <fcntl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <fstream>
#include "openssl/sha.h"
std::vector<File> FileUtility::files;
std::vector<IncompleteFile*> FileUtility::incompletefiles;
FileUtility::~FileUtility() {
for (auto it : incompletefiles) {
delete it;
}
incompletefiles.clear();
}
void FileUtility::prepfile(const std::string& filepath) {
std::cout << "Preparing File: " << filepath << std::endl;
uint64_t size = 0;
@ -19,6 +30,14 @@ File FileUtility::getFile(const std::string& hash) {
}
return File("", "", 0);
}
File FileUtility::getFileByName(const std::string& name) {
for (auto it : files) {
if (it.filename == name)
;
return it;
}
return File("", "", 0);
}
std::string FileUtility::hashblock(char* data, uint64_t size) {
unsigned char hash[SHA256_DIGEST_LENGTH];
SHA256_CTX sha256;
@ -27,6 +46,15 @@ std::string FileUtility::hashblock(char* data, uint64_t size) {
SHA256_Final(hash, &sha256);
return sha256_hash_string(hash);
}
IncompleteFile* FileUtility::getIncompleteFile(const std::string& hash) {
for (auto it : incompletefiles) {
// std::cout << "Check: " << it->hash << " - " << hash << std::endl;
if (it->hash == hash)
return it;
std::cout << "Chck Failed!" << std::endl;
}
return nullptr;
}
std::string FileUtility::hashfile(const std::string& filepath,
uint64_t* filesize) {
@ -72,7 +100,31 @@ std::string FileUtility::sha256_hash_string(
return outputBuffer;
}
void FileUtility::createWithSize(const std::string& filename, uint64_t size) {
std::ofstream ofs(filename, std::ios::binary);
ofs.seekp(size - 1);
ofs.write("", 1);
ofs.flush();
ofs.close();
}
void FileUtility::copyData(const std::string& filename,
uint64_t p,
char* data,
uint64_t size) {
int writesocket = open(filename.c_str(), O_WRONLY);
lseek64(writesocket, p, SEEK_SET);
if (write(writesocket, data, size) != (int64_t)size) {
std::cout << "Error Writing File!";
}
close(writesocket);
}
File::File(const std::string& filename,
const std::string& hash,
const uint64_t& filesize)
: filename(filename), hash(hash), filesize(filesize){};
: filename(filename), hash(hash), filesize(filesize) {}
IncompleteFile::IncompleteFile(const std::string& filename,
const std::string& hash,
const uint64_t& filesize,
const uint64_t chunks)
: filename(filename), hash(hash), filesize(filesize), chunks(chunks) {}

@ -1,8 +1,13 @@
#include <unistd.h>
#include <algorithm>
#include <iostream>
#include <iterator>
#include <sstream>
#include <thread>
#include <vector>
#include "fileutility.hpp"
#include "settings.hpp"
#include "trackserver.hpp"
#include "udpclient.hpp"
#include "udpserver.hpp"
UDPServer server;
@ -12,16 +17,125 @@ int main(int argc, char* argv[]) {
Settings::readArgs(argc, argv);
std::cout << "Starting on Port " << Settings::port << "!" << std::endl;
Settings::running = true;
UDPClient udpc("127.0.0.1", 0);
std::thread server(&startUDPServer);
FileUtility::prepfile("testfile");
UDPClient client("127.0.0.1", DEF_PORT);
usleep(10000);
for (auto it : FileUtility::files) {
std::cout << "Requesting info! " << it.hash << std::endl;
client.requestInfo(it.hash);
TrackServerManager tmgr;
if (Settings::ep != nullptr) {
std::string addr = Settings::ep;
int t_port;
std::string t_addr;
if (addr.find(':') <= addr.length()) {
std::string ip = addr.substr(0, addr.find(":"));
std::string port = addr.substr(addr.find(":") + 1, addr.length());
int portnum = -1;
std::stringstream ss;
ss << port;
ss >> portnum;
t_port = portnum;
t_addr = ip;
} else {
t_addr = addr;
t_port = DEF_PORT;
}
tmgr.addTracker(t_addr, t_port);
}
while (Settings::running) {
char cmda[512];
std::cin.getline(cmda, sizeof(cmda));
std::string cmd = cmda;
std::transform(cmd.begin(), cmd.end(), cmd.begin(),
[](unsigned char c) { return std::tolower(c); });
std::istringstream iss(cmd);
std::string data;
std::string args[8];
int ptr = 0;
while (std::getline(iss, data, ' ')) {
args[ptr] = data;
if (ptr >= 8)
break;
ptr++;
}
if (cmd.find("addtracker") == 0) {
std::string addr = args[1];
int t_port;
std::string t_addr;
if (addr.find(':') <= addr.length()) {
std::string ip = addr.substr(0, addr.find(":"));
std::string port = addr.substr(addr.find(":") + 1, addr.length());
int portnum = -1;
std::stringstream ss;
ss << port;
ss >> portnum;
t_port = portnum;
t_addr = ip;
} else {
t_addr = addr;
t_port = DEF_PORT;
}
if (t_addr != "") {
tmgr.addTracker(t_addr, t_port);
}
}
if (cmd.find("advertise") == 0) {
std::string adv = args[1];
FileUtility::prepfile(adv);
File fi = FileUtility::getFileByName(adv);
if (fi.filename != "") {
std::cout << "Hash: " << fi.hash << std::endl;
tmgr.AnnounceHash(fi.hash);
} else {
std::cerr << "Incorrect Filename!";
}
}
if (cmd.find("request") == 0) {
std::string addr = tmgr.AskHash(args[1]);
int t_port;
std::string t_addr;
if (addr.find(':') <= addr.length()) {
std::string ip = addr.substr(0, addr.find(":"));
std::string port = addr.substr(addr.find(":") + 1, addr.length());
int portnum = -1;
std::stringstream ss;
ss << port;
ss >> portnum;
t_port = portnum;
t_addr = ip;
} else {
t_addr = addr;
t_port = DEF_PORT;
}
if (t_addr != "") {
udpc.setdata(t_addr, t_port);
udpc.requestInfo(args[1]);
usleep(100000);
IncompleteFile* ifc = FileUtility::getIncompleteFile(args[1]);
bool izzda = false;
while (!izzda) {
if (ifc != nullptr) {
bool pre = true;
std::cout << "aaa" << std::endl;
for (uint64_t chunkfind = 0; chunkfind != ifc->chunks;
chunkfind++) {
if ((std::find(ifc->chunksset.begin(), ifc->chunksset.end(),
chunkfind) != ifc->chunksset.end())) {
pre = false;
std::cout << "bb" << std::endl;
} else {
udpc.requestChunk(args[1], chunkfind);
usleep(1000 * 20);
}
}
izzda = pre;
} else {
std::cout << "Error requesting File!" << std::endl;
break;
}
}
}
}
}
if (server.joinable())
server.join();

@ -1,101 +1,216 @@
#include "packetmanager.hpp"
#include <fcntl.h>
#include <netinet/in.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <algorithm>
#include <fstream>
#include "fileutility.hpp"
#include "protocol.hpp"
PacketManager::PacketManager() {}
void PacketManager::handlePacket_data(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic) {
switch (basic.pid) {
case p_p_block:
if (size >= sizeof(FileDataPacket))
handlePacket_data_data(fd, data, size, client, basic);
break;
case p_p_info:
if (size >= sizeof(FileInfoPacket))
handlePacket_data_info(fd, data, size, client, basic);
break;
}
}
void PacketManager::handlePacket_request(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic) {
switch (basic.pid) {
case p_p_block:
handlePacket_req_data(fd, data, size, client, basic);
break;
case p_p_info:
handlePacket_req_info(fd, data, size, client, basic);
break;
default:
sendError(fd, data, size, client);
break;
}
}
void PacketManager::manageData(int fd,
char* data,
unsigned long size,
void* client) {
struct sockaddr_in clientaddr = *((struct sockaddr_in*)client);
if (size >= sizeof(Packet)) {
Packet basic = *((Packet*)data);
if (basic.identifier == p_identifier_req) {
if ((basic.pid == p_p_block) && (size >= sizeof(FileDataPacket))) {
FileDataPacket packet = *((FileDataPacket*)data);
File f = FileUtility::getFile(packet.file_hash);
std::cout << "Block Request! -> " << packet.file_hash << std::endl;
switch (basic.identifier) {
case p_identifier_req:
handlePacket_request(fd, data, size, client, basic);
break;
case p_identifier_send:
handlePacket_data(fd, data, size, client, basic);
break;
default:
sendError(fd, data, size, client);
break;
}
} else {
std::cerr << "Smallest Packet ever!" << std::endl;
sendError(fd, data, size, client);
}
}
void PacketManager::handlePacket_req_info(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic) {
struct sockaddr_in clientaddr = *((struct sockaddr_in*)client);
FileInfoPacket packet = *((FileInfoPacket*)data);
File f = FileUtility::getFile(packet.file_hash);
std::cout << "info Request! -> " << packet.file_hash << std::endl;
if (f.hash != "") {
std::cout << "File Found! -> " << packet.file_hash << std::endl;
if (f.hash != "") {
std::cout << "File found! -> " << packet.file_hash << std::endl;
FileDataPacket toSend;
toSend.identifier = p_identifier_send;
toSend.chunkid = packet.chunkid;
memcpy(toSend.file_hash, packet.file_hash, sizeof(packet.file_hash));
std::ifstream is(f.filename, std::ifstream::binary);
if (is) {
if (toSend.chunkid <= 0)
is.seekg(0);
else
is.seekg(packet.chunkid * blocksize + 1);
is.read(packet.data, blocksize);
std::string hash = FileUtility::hashblock(toSend.data, blocksize);
memcpy(toSend.data_hash, hash.c_str(), hash.length());
sendto(fd, &toSend, sizeof(toSend), MSG_CONFIRM,
(const struct sockaddr*)&clientaddr, sizeof(clientaddr));
} else {
std::cerr << "Couldn't read file! -> " << packet.file_hash
<< std::endl;
Packet toSend;
toSend.identifier = p_identifier_send;
memset(&toSend.file_hash, 0, sizeof(toSend.file_hash));
sendto(fd, &toSend, sizeof(toSend), MSG_CONFIRM,
(const struct sockaddr*)&clientaddr, sizeof(clientaddr));
}
FileInfoPacket toSend;
toSend.identifier = p_identifier_send;
memcpy(toSend.file_hash, f.hash.c_str(), f.hash.length() + 1);
memcpy(toSend.filename, f.filename.c_str(), f.filename.length() + 1);
toSend.filesize = f.filesize;
sendto(fd, &toSend, sizeof(toSend), MSG_CONFIRM,
(const struct sockaddr*)&clientaddr, sizeof(clientaddr));
} else {
std::cout << "Couldn't read / find file! -> " << packet.file_hash
<< std::endl;
} else {
std::cerr << "Couldn't find file! -> " << packet.file_hash << std::endl;
sendError(fd, data, size, client);
}
}
void PacketManager::handlePacket_req_data(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic) {
struct sockaddr_in clientaddr = *((struct sockaddr_in*)client);
FileDataRequestPacket packet = *((FileDataRequestPacket*)data);
File f = FileUtility::getFile(packet.file_hash);
// std::cout << "Block Request! -> " << packet.file_hash << std::endl;
if (f.hash != "") {
// std::cout << "File Found! -> " << packet.file_hash << std::endl;
Packet toSend;
toSend.identifier = p_identifier_send;
memset(&toSend.file_hash, 0, sizeof(toSend.file_hash));
sendto(fd, &toSend, sizeof(toSend), MSG_CONFIRM,
(const struct sockaddr*)&clientaddr, sizeof(clientaddr));
}
FileDataPacket toSend;
toSend.identifier = p_identifier_send;
toSend.chunkid = packet.chunkid;
} else if ((basic.pid = p_p_info) && (size >= sizeof(FileInfoPacket))) {
FileInfoPacket packet = *((FileInfoPacket*)data);
File f = FileUtility::getFile(packet.file_hash);
std::cout << "info Request! -> " << packet.file_hash << std::endl;
memcpy(toSend.file_hash, packet.file_hash, sizeof(packet.file_hash));
// std::cout << "FileName: " << f.filename << std::endl;
int is = open(f.filename.c_str(), O_RDONLY);
if (is > 0) {
if (toSend.chunkid <= 0)
lseek64(is, 0, SEEK_SET);
else
lseek64(is, (toSend.chunkid * blocksize), SEEK_SET);
uint16_t size = read(is, toSend.data, sizeof(toSend.data));
close(is);
toSend.datasize = size;
std::string hash = FileUtility::hashblock(toSend.data, blocksize);
memcpy(toSend.data_hash, hash.c_str(), hash.length());
sendto(fd, &toSend, sizeof(toSend), MSG_CONFIRM,
(const struct sockaddr*)&clientaddr, sizeof(clientaddr));
} else {
std::cerr << "Couldn't read file! -> " << packet.file_hash << std::endl;
Packet toSend;
toSend.identifier = p_identifier_send;
memset(&toSend.file_hash, 0, sizeof(toSend.file_hash));
sendto(fd, &toSend, sizeof(toSend), MSG_CONFIRM,
(const struct sockaddr*)&clientaddr, sizeof(clientaddr));
}
if (f.hash != "") {
std::cout << "File found! -> " << packet.file_hash << std::endl;
} else {
std::cout << "Wrong Hesh!" << std::endl;
sendError(fd, data, size, client);
}
}
void PacketManager::handlePacket_data_info(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic) {
FileInfoPacket fip = *((FileInfoPacket*)data);
std::cout << "Got Info!" << std::endl;
bool fine = true;
for (auto i : FileUtility::files) {
if (i.hash == fip.file_hash) {
fine = false;
break;
}
}
std::ifstream f(fip.filename);
if (fine)
fine = !f.good();
FileInfoPacket toSend;
toSend.identifier = p_identifier_send;
memcpy(toSend.file_hash, f.hash.c_str(), f.hash.length());
memcpy(toSend.filename, f.filename.c_str(), f.filename.length());
toSend.filesize = f.filesize;
sendto(fd, &toSend, sizeof(toSend), MSG_CONFIRM,
(const struct sockaddr*)&clientaddr, sizeof(clientaddr));
if (fine) {
std::cout << "Preparing for File with NAME: " << fip.filename
<< ", HASH: " << fip.file_hash << ", and Size: " << fip.filesize
<< std::endl;
FileUtility::createWithSize(fip.filename, 1);
IncompleteFile* f =
new IncompleteFile(fip.filename, fip.file_hash, fip.filesize,
(fip.filesize / blocksize) + 1);
FileUtility::incompletefiles.push_back(f);
} else {
std::cout << "Wtf? I already have this file!" << std::endl;
}
}
} else {
std::cerr << "Couldn't find file! -> " << packet.file_hash
<< std::endl;
void PacketManager::handlePacket_data_data(int fd,
char* data,
unsigned long& size,
void* client,
Packet& basic) {
FileDataPacket packet = *((FileDataPacket*)data);
std::string hash = FileUtility::hashblock(packet.data, sizeof(packet.data));
if (hash != packet.data_hash) {
std::cerr << "Corrupt Block!";
} else {
IncompleteFile* inf = FileUtility::getIncompleteFile(packet.file_hash);
if (inf != nullptr) {
// std::cout << "Block is Correct & given! ID: " << packet.chunkid
// << std::endl;
Packet toSend;
toSend.identifier = p_identifier_send;
memset(&toSend.file_hash, 0, sizeof(toSend.file_hash));
sendto(fd, &toSend, sizeof(toSend), MSG_CONFIRM,
(const struct sockaddr*)&clientaddr, sizeof(clientaddr));
}
uint64_t chunk = packet.chunkid;
if (std::find(inf->chunksset.begin(), inf->chunksset.end(), chunk) !=
inf->chunksset.end()) {
std::cerr << "Already have Chunk: " << chunk << std::endl;
} else {
std::cout << "Wtf?!" << std::endl;
inf->chunksset.push_back(chunk);
uint64_t p = chunk * blocksize;
Packet toSend;
toSend.identifier = p_identifier_send;
memset(&toSend.file_hash, 0, sizeof(toSend.file_hash));
sendto(fd, &toSend, sizeof(toSend), MSG_CONFIRM,
(const struct sockaddr*)&clientaddr, sizeof(clientaddr));
FileUtility::copyData(inf->filename, p, packet.data, packet.datasize);
}
} else if (basic.identifier == p_identifier_send) {
} else {
std::cerr << "Hash broken!" << std::endl;
}
}
}
void PacketManager::sendError(int fd,
char* data,
unsigned long& size,
void* client) {
struct sockaddr_in clientaddr = *((struct sockaddr_in*)client);
Packet toSend;
toSend.identifier = p_identifier_send;
memset(&toSend.file_hash, 0, sizeof(toSend.file_hash));
sendto(fd, &toSend, sizeof(toSend), MSG_CONFIRM,
(const struct sockaddr*)&clientaddr, sizeof(clientaddr));
}

@ -7,24 +7,24 @@
void Settings::readArgs(int argc, char* argv[]) {
static const struct option longopts[] = {
{"port", optional_argument, 0, 'p'},
{"endpoint", optional_argument, 0, 'e'},
{"tracker", optional_argument, 0, 't'},
0};
int index = 0;
int c;
std::stringstream str;
while ((c = getopt_long(argc, argv, "p:e:", longopts, &index)) != -1) {
while ((c = getopt_long(argc, argv, "p:t:", longopts, &index)) != -1) {
switch (c) {
case 'p':
str << optarg;
str >> port;
break;
case 'e':
case 't':
Settings::ep = optarg;
break;
default:
fprintf(stderr, "Usage: %s [--port port] [--endpoint ip]\n", argv[0]);
fprintf(stderr, "Usage: %s [--port port] [--tracker ip]\n", argv[0]);
exit(EXIT_FAILURE);
break;
}

@ -0,0 +1,77 @@
#include "trackserver.hpp"
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <unistd.h>
#include "settings.hpp"
int TrackServerManager::connectTo(TrackServer ts) {
int sock;
struct sockaddr_in serv_addr;
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
printf("\n Socket creation error \n");
return -1;
}
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(ts.port);
// Convert IPv4 and IPv6 addresses from text to binary form
if (inet_pton(AF_INET, ts.addr.c_str(), &serv_addr.sin_addr) <= 0) {
printf("\nInvalid address/ Address not supported \n");
return -1;
}
if (connect(sock, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0) {
printf("\nConnection Failed \n");
return -1;
}
return sock;
}
void TrackServerManager::AnnounceHash(const std::string hash) {
for (auto it : trackers) {
int socket = connectTo(it);
if (socket > 0) {
TrackerPacket tp;
tp.searching = 'n';
tp.portn = Settings::port;
memcpy(tp.hash, hash.c_str(), hash.length() + 1);
if (write(socket, &tp, sizeof(tp)) != sizeof(tp)) {
std::cerr << "Error sending TrackerPacket!";
}
} else {
std::cerr << "Tracker Error!";
}
}
}
std::string TrackServerManager::AskHash(const std::string hash) {
for (auto it : trackers) {
int socket = connectTo(it);
if (socket > 0) {
TrackerPacket tp;
tp.searching = 'y';
tp.portn = 0;
memcpy(tp.hash, hash.c_str(), hash.length());
if (write(socket, &tp, sizeof(tp)) != sizeof(tp)) {
std::cerr << "Error sending TrackerPacket!";
}
char buffer[sizeof(TrackerPacket)];
if (read(socket, &buffer, sizeof(buffer)) != sizeof(buffer)) {
std::cerr << "Error reading Trackerpacket!";
}
TrackerPacket tpb = *((TrackerPacket*)buffer);
return std::string(tpb.addr);
} else {
std::cerr << "Tracker Error!";
}
}
return "Error!";
}
void TrackServerManager::addTracker(const std::string& addr, int port) {
TrackServer ts;
ts.addr = addr;
ts.port = port;
trackers.push_back(ts);
std::cout << "added Tracker, " << ts.addr << ":" << std::to_string(port)
<< std::endl;
}

@ -8,11 +8,22 @@
#include <sys/types.h>
#include <sstream>
UDPClient::UDPClient(const std::string& addr, int port)
: addr(addr), port(port) {
UDPClient::UDPClient(const std::string& addr, int port) {
setdata(addr, port);
createSocket();
this->pmgr = new PacketManager();
}
UDPClient::UDPClient(const std::string& addr) {
setdata(addr);
createSocket();
this->pmgr = new PacketManager();
}
void UDPClient::setdata(const std::string& addr, int port) {
this->addr = addr;
this->port = port;
}
void UDPClient::setdata(const std::string& addr) {
if (addr.find(':') <= addr.length()) {
std::string ip = addr.substr(0, addr.find(":"));
std::string port = addr.substr(addr.find(":") + 1, addr.length());
@ -26,7 +37,9 @@ UDPClient::UDPClient(const std::string& addr) {
this->addr = addr;
this->port = DEF_PORT;
}
createSocket();
}
UDPClient::~UDPClient() {
delete pmgr;
}
void UDPClient::createSocket() {
if ((clientsocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
@ -43,7 +56,62 @@ void UDPClient::requestInfo(const std::string& hash) {
FileInfoPacket fip;
fip.identifier = p_identifier_req;
memcpy(fip.file_hash, hash.c_str(), hash.length());
memcpy(fip.file_hash, hash.c_str(), hash.length() + 1);
sendto(clientsocket, &fip, sizeof(fip), MSG_CONFIRM,
(const struct sockaddr*)&serveraddr, sizeof(serveraddr));
char buffer[sizeof(FileInfoPacket)];
socklen_t len;
int n;
memset(buffer, 0, sizeof(buffer));
len = sizeof(serveraddr); // len is value/result
n = recvfrom(clientsocket, (char*)buffer, sizeof(buffer), 0,
(struct sockaddr*)&serveraddr, &len);
if (n < 0)
std::cerr << "Error Reading!";
else
pmgr->manageData(clientsocket, (char*)buffer, n, &serveraddr);
}
void UDPClient::requestChunk(const std::string& hash, uint64_t chunk) {
// std::cout << "Requesting: " << hash << "###" << chunk << std::endl;
struct sockaddr_in serveraddr;
memset(&serveraddr, 0, sizeof(serveraddr));
serveraddr.sin_family = AF_INET;
serveraddr.sin_port = htons(port);
inet_pton(AF_INET, addr.c_str(), &(serveraddr.sin_addr));
FileDataRequestPacket fip;
fip.identifier = p_identifier_req;
fip.pid = p_p_block;
fip.chunkid = chunk;
memcpy(fip.file_hash, hash.c_str(), hash.length() + 1);
// std::cout << "Requesting for Packet! " << chunk << std::endl;
sendto(clientsocket, &fip, sizeof(fip), MSG_CONFIRM,
(const struct sockaddr*)&serveraddr, sizeof(serveraddr));
}
char buffer[sizeof(FileDataPacket)];
socklen_t len;
int n;
memset(buffer, 0, sizeof(buffer));
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 140000;
if (setsockopt(clientsocket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)) < 0) {
perror("Packet went missing!");
exit(0);
}
// std::cout << "Waiting for Packet! " << chunk << std::endl;
len = sizeof(serveraddr); // len is value/result
n = recvfrom(clientsocket, (char*)buffer, sizeof(buffer), 0,
(struct sockaddr*)&serveraddr, &len);
if (n < 0) {
// std::cerr << "Error Reading!" << std::endl;
} else {
// std::cout << "Read " << n << std::endl;
pmgr->manageData(clientsocket, (char*)buffer, n, &serveraddr);
}
}

@ -16,7 +16,7 @@ UDPServer::~UDPServer() {
}
void UDPServer::start() {
std::cout << "Starting UDP Server on Port " << Settings::port;
std::cout << "Starting UDP Server on Port " << Settings::port << std::endl;
struct sockaddr_in serveraddr, clientaddr;
if ((serversocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) < 0) {
@ -38,13 +38,15 @@ void UDPServer::start() {
perror("bind failed");
exit(EXIT_FAILURE);
}
memset(&clientaddr, 0, sizeof(serveraddr));
socklen_t len;
len = sizeof(clientaddr); // len is value/result
while (Settings::running) {
memset(&clientaddr, 0, sizeof(serveraddr));
char buffer[sizeof(FileDataPacket)];
socklen_t len;
int n;
len = sizeof(clientaddr); // len is value/result
n = recvfrom(serversocket, (char*)buffer, blocksize, MSG_WAITALL,
n = recvfrom(serversocket, (char*)buffer, sizeof(buffer), MSG_WAITALL,
(struct sockaddr*)&clientaddr, &len);
if (n < 0)

Loading…
Cancel
Save