...
authoralex <[email protected]>
Tue, 1 Mar 2022 00:30:15 +0000 (16:30 -0800)
committeralex <[email protected]>
Tue, 1 Mar 2022 00:30:15 +0000 (16:30 -0800)
inc/block.h
src/block.c
src/file.c
src/torrent/piece.c

index 7adec69392959590970570bb78931ba8cf1da472..00e973879bb1859b890971dcffd06d7f3ddc3813 100644 (file)
@@ -18,7 +18,7 @@ struct block {
 void block_free(struct block*);
 int block_init(struct block**);
 size_t block_length(struct block*);
-int block_merkle_layer(struct block*);
+int block_merkle_layer(struct block*,struct block**);
 int block_merkle_root(struct block*);
 int block_pad(struct block*);
 
index 7b94901203a3937b826664e04554c249225dc585..76b2a21d03e68111c81d678947cb8741b577da09 100644 (file)
@@ -38,13 +38,21 @@ size_t block_length(struct block *p) {
 
 const static unsigned char zerod[crypto_hash_sha256_BYTES] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
 
-int block_merkle_layer(struct block *root) {
-       struct block *p, *to_free;
+int block_merkle_layer(struct block *root, struct block **next_layer) {
+       struct block *p, *tail;
        crypto_hash_sha256_state state;
-       
+       int i;
+
        if(NULL==root) { return -1; }
+       if(NULL==next_layer) { return -1; }
+
+       tail = root;
+       while(tail->next!=NULL) {
+               tail = tail->next;
+       }
 
        p = root;
+       i = 0;
        while(p!=NULL) {
                if((NULL==p->next)&&(p==root)) { break; }
                if(hash_init(&state)<0) { return -1; }
@@ -56,21 +64,18 @@ int block_merkle_layer(struct block *root) {
                        if(hash_update(&state,zerod,crypto_hash_sha256_BYTES)<0) { return -1; }
                }
                
-               if(hash_final(&state,p->hash,crypto_hash_sha256_BYTES)<0) { return -1; }
-               
-               to_free = p->next;
-               if(p->next!=NULL) {
-                       p->next = p->next->next;
-               } else {
-                       p->next = NULL;
-               }
-               
-               if(to_free!=NULL) {
-                       to_free->next = NULL;
-                       block_free(to_free);
-               }
-       
+               if(block_init(&(tail->next))<0) { return -1; }
+               tail = tail->next;
+
+               if(hash_final(&state,tail->hash,crypto_hash_sha256_BYTES)<0) { return -1; }
+
+               // set index, marking as padding if both leaves are padding
+               tail->index = ((p->index<0)||(p->next->index<0))?-1:i;
+
+               if(NULL==(*next_layer)) { (*next_layer) = tail; }
+
                p = p->next;
+               i++;
        }
 
        return 1;
@@ -81,10 +86,9 @@ int block_merkle_root(struct block *root) {
        if(NULL==root) { return -1; }
 
        end = NULL;
-       while(root->next!=NULL) {
-               end = block_merkle_layer(root,end);
-               if(NULL==end) { return -1; }
-       }
+       do {
+               if(block_merkle_layer(root,&end)<0) { return -1; }
+       } while(end->index>0);
 
        return 1;
 }
index a6781e1b553e5d1b4dac90c01d2b90d9262dca24..9ec06d8df2006c7fad02c75f5d2ed9c37b5022ce 100644 (file)
@@ -1,6 +1,7 @@
 #include<file.h>
 
-static int file_piece_layers(struct file *p, int piece_length);
+static int file_merkle_root(struct file*);
+static int file_piece_layers(struct file*,int);
 static int advance(ssize_t,uint8_t**,size_t*);
 
 static int advance(ssize_t i, uint8_t **buf, size_t *len) {
@@ -131,12 +132,12 @@ int file_hash(struct file *file_p, int piece_length) {
 
        fclose(fp);
 
-       if(block_length(p)>1) {
+       if(p->next!=NULL) { // i.e. more than 1 block
                if(block_pad(p)<0) { goto clean; }
        }
 
-       if(block_merkle_root(p)<0) { goto clean; }
        if(file_piece_layers(file_p,piece_length)<0) { return -1; }
+       if(file_merkle_root(file_p)<0) { goto clean; }
        
        return 1;
 clean:
@@ -144,30 +145,20 @@ clean:
        return -1;
 }
 
+static int file_merkle_root(struct file *file_p) {
+       return -1;
+}
+
 static int file_piece_layers(struct file *file_p, int piece_length) {
-       struct block *p, *last;
-       size_t blocks;
+       struct block *p;
        int ratio;
 
        ratio = piece_length / BLOCK_SIZE;
 
-       blocks = 0;
-       p = file_p->piece_layers;
-       last = p;
-       while(p->next!=NULL) {
-               p = p->next;
-               blocks++;
-               if(blocks%ratio==0) {
-                       last = p;
-               }
-       }
-
-       for(int i=1;i<ratio;i<<=1) {
-               if(block_pad(last)<0) { return -1; }
-       }
-
+       p = file_p->blocks;
        while(ratio>1) {
-               if(block_merkle_layer(file_p->piece_layers)<0) { return -1; }
+               if(block_merkle_layer(p,&(file_p->piece_layers))<0) { return -1; }
+               p = file_p->piece_layers;
                ratio>>=1;
        }
 
index d788e1a7f5e054fd106cebaad244598802d6ead8..9e595599c60c886b6674e248dfcdaa2cdb21021c 100644 (file)
@@ -11,7 +11,7 @@ static int torrent_bencode_piece_layers(FILE *fp, struct file *file_p) {
        ssize_t i;
        uint8_t buf[PIECE_LAYER_BENCODED_LENGTH];
 
-       if((i = bencode_string(file_p->root,crypto_hash_sha256_BYTES,buf,PIECE_LAYER_BENCODED_LENGTH))<0) { return -1; }
+       if((i = bencode_string(file_p->root->hash,crypto_hash_sha256_BYTES,buf,PIECE_LAYER_BENCODED_LENGTH))<0) { return -1; }
        if(fwrite(buf,sizeof(uint8_t),i,fp)!=i) { return -1; }
 
        blocks = block_length(file_p->piece_layers);
@@ -50,7 +50,7 @@ int torrent_file_piece_layers(FILE *fp, struct torrent *p) {
                file_p = (struct file*)p->files.roots->map[i];
                if(file_p!=NULL) {
                        if(file_p->size>p->piece_length) {
-                               hashes[index] = file_p->root;
+                               hashes[index] = file_p->root->hash;
                                index++;
                        }
                }