return ret_str[i];
}
+
+Address::Address(const char* ip_port) {
+ clear();
+ if (strlen(ip_port)>=32)
+ return;
+ char ipp[32];
+ strncpy(ipp,ip_port,32);
+ char* semi = strchr(ipp,':');
+ if (semi) {
+ *semi = 0;
+ set_ipv4(ipp);
+ set_port(semi+1);
+ } else {
+ if (strchr(ipp, '.')) {
+ set_ipv4(ipp);
+ set_port((uint16_t)0);
+ } else {
+ set_ipv4(INADDR_LOOPBACK);
+ set_port(ipp);
+ }
+ }
+}
+
+
int Datagram::Send () {
int r = sendto(sock,(const char *)buf+offset,length-offset,0,
(struct sockaddr*)&(addr.addr),sizeof(struct sockaddr_in));
struct Address {
struct sockaddr_in addr;
static uint32_t LOCALHOST;
- void init(uint32_t ipv4=0, uint16_t port=0) {
- memset(&addr,0,sizeof(struct sockaddr_in));
- addr.sin_family = AF_INET;
+ void set_port (uint16_t port) {
addr.sin_port = htons(port);
+ }
+ void set_port (const char* port_str) {
+ int p;
+ if (sscanf(port_str,"%i",&p))
+ set_port(p);
+ }
+ void set_ipv4 (uint32_t ipv4) {
addr.sin_addr.s_addr = htonl(ipv4);
}
- Address() { init(); }
- Address(const char* ip, uint16_t port) {
- init(LOCALHOST,port);
- inet_aton(ip,&(addr.sin_addr));
+ void set_ipv4 (const char* ipv4_str) {
+ inet_aton(ipv4_str,&(addr.sin_addr));
+ }
+ void clear () {
+ memset(&addr,0,sizeof(struct sockaddr_in));
+ addr.sin_family = AF_INET;
+ }
+ Address() {
+ clear();
}
- Address(const char* ip_port) {
- char ipp[32];
- strcpy(ipp,ip_port);
- char* semi = strchr(ipp,':');
- if (semi) {
- *semi = 0;
- int port;
- sscanf(semi+1, "%i", &port);
- init(LOCALHOST,port);
- }
- inet_aton(ipp,&(addr.sin_addr));
+ Address(const char* ip, uint16_t port) {
+ clear();
+ set_ipv4(ip);
+ set_port(port);
}
+ Address(const char* ip_port);
Address(uint16_t port) {
- init(LOCALHOST,port);
+ clear();
+ set_ipv4(LOCALHOST);
+ set_port(port);
}
Address(uint32_t ipv4addr, uint16_t port) {
- init(ipv4addr,port);
+ clear();
+ set_ipv4(ipv4addr);
+ set_port(port);
}
Address(const struct sockaddr_in& address) : addr(address) {}
uint32_t ipv4 () const { return ntohl(addr.sin_addr.s_addr); }
/** P2TP downloader. Params: root hash, filename, tracker ip/port, own ip/port */
int main (int argn, char** args) {
+ srand(time(NULL));
+ FileTransfer::instance = rand();
+
if (argn<4) {
fprintf(stderr,"parameters: root_hash filename tracker_ip/port [own_ip/port]\n");
return -1;
p2tp::SetTracker(tracker);
int file = p2tp::Open(filename,root_hash);
+ printf("Downloading %s\n",root_hash.hex().c_str());
while (!p2tp::Complete(file)) {
- p2tp::Loop(TINT_SEC/100);
+ p2tp::Loop(TINT_SEC);
printf("%lli dgram %lli bytes up, %lli dgram %lli bytes down\n",
Datagram::dgrams_up, Datagram::bytes_up,
Datagram::dgrams_down, Datagram::bytes_down );
char* filename = args[1];
- Address tracker(args[3]), bindaddr(args[2]);
+ if (argn>=4) {
+ Address tracker(args[3]);
+ p2tp::SetTracker(tracker);
+ }
+ Address bindaddr(args[2]);
if (bindaddr==Address()) {
fprintf(stderr,"Bind address format: [1.2.3.4:]12345\n");
}
assert(0<p2tp::Listen(bindaddr));
+ printf("seeder bound to %s\n",bindaddr.str().c_str());
- if (tracker!=Address())
- p2tp::SetTracker(tracker);
int file = p2tp::Open(filename);
+ printf("seeding %s %s\n",filename,RootMerkleHash(file).hex().c_str());
while (true) {
- p2tp::Loop(TINT_SEC);
+ p2tp::Loop(TINT_SEC*60);
printf("%lli dgram %lli bytes up, %lli dgram %lli bytes down\n",
Datagram::dgrams_up, Datagram::bytes_up,
Datagram::dgrams_down, Datagram::bytes_down );
}
-
+const Sha1Hash& p2tp::RootMerkleHash (int file) {
+ FileTransfer* trans = FileTransfer::file(file);
+ if (!trans)
+ return Sha1Hash::ZERO;
+ return trans->root_hash();
+}
/** <h2> P2TP handshake </h2>
/** Open a file, start a transmission; fill it with content for a given root hash;
in case the hash is omitted, the file is a fresh submit. */
int Open (const char* filename, const Sha1Hash& hash=Sha1Hash::ZERO) ;
+ /** Get the root hash for the transmission. */
+ const Sha1Hash& RootMerkleHash (int file) ;
/** Close a file and a transmission. */
void Close (int fd) ;
/** Add a possible peer which participares in a given transmission. In the case
RETLOG ("invalid peer address");
channel->own_id_mentioned_ = true;
}
+ dprintf("recvd %i bytes for %i\n",data.size(),channel->id);
channel->Recv(data);
}