From: alex Date: Thu, 23 Dec 2021 20:43:50 +0000 (-0800) Subject: ... X-Git-Url: http://git.infiniteadaptability.org/?a=commitdiff_plain;h=4ad3d89b551e688d91ef4d018a1df1ef73a97cc3;p=seeder ... --- diff --git a/src/bencode/encode.c b/src/bencode/encode.c index 6da2000..ef1ccd1 100644 --- a/src/bencode/encode.c +++ b/src/bencode/encode.c @@ -2,7 +2,7 @@ ssize_t bencode_dict_end(uint8_t *output, size_t output_size) { if(NULL==output) { return -1; } - if(output_size<=1) { return -1; } + if(output_size<1) { return -1; } output[0] = 'e'; @@ -11,7 +11,7 @@ ssize_t bencode_dict_end(uint8_t *output, size_t output_size) { ssize_t bencode_dict_start(uint8_t *output, size_t output_size) { if(NULL==output) { return -1; } - if(output_size<=1) { return -1; } + if(output_size<1) { return -1; } output[0] = 'd'; diff --git a/src/torrent/info.c b/src/torrent/info.c index 71f8474..28d63f6 100644 --- a/src/torrent/info.c +++ b/src/torrent/info.c @@ -1,9 +1,12 @@ #include -static size_t torrent_file_info_length(struct tree *tree); +static size_t torrent_file_info_length(struct torrent*); static uint8_t file_tree_string[] = "file tree"; static uint8_t meta_version_string[] = "meta version"; + +#define TORRENT_FILE_META_VERSION 2 + static uint8_t name_string[] = "name"; static uint8_t piece_length_string[] = "piece length"; @@ -13,7 +16,7 @@ ssize_t torrent_file_info(struct torrent *torrent_p, uint8_t **buf) { if(NULL==buf) { return -1; } - buf_len = torrent_file_info_length(torrent_p->tree); + buf_len = torrent_file_info_length(torrent_p); p = malloc(sizeof(uint8_t)*buf_len); if(NULL==p) { return -1; } @@ -28,7 +31,7 @@ ssize_t torrent_file_info(struct torrent *torrent_p, uint8_t **buf) { if((i = bencode_string(meta_version_string,sizeof(meta_version_string)-1,&(p[len]),buf_len-len))<0) { goto clean; } len += i; - if((i = bencode_int(2,&(p[len]),buf_len-len))<0) { goto clean; } + if((i = bencode_int(TORRENT_FILE_META_VERSION,&(p[len]),buf_len-len))<0) { goto clean; } len += i; if((i = bencode_string(name_string,sizeof(name_string)-1,&(p[len]),buf_len-len))<0) { goto clean; } @@ -41,24 +44,35 @@ ssize_t torrent_file_info(struct torrent *torrent_p, uint8_t **buf) { if((i = bencode_int(torrent_p->piece_length,&(p[len]),buf_len-len))<0) { goto clean; } len += i; + if((i = bencode_dict_end(&(p[len]),buf_len-len))<0) { goto clean; } + len += i; + + (*buf) = p; + return len; clean: free(p); return -1; } -static size_t torrent_file_info_length(struct tree *tree) { - size_t i; +static size_t torrent_file_info_length(struct torrent *p) { + size_t i, len; - i = 0; + i = 2; // opening '{' (d) and ending '}' (e) // string length = sizeof()-1, +1 for ':' included i += sizeof(file_tree_string)+bencode_size_int(sizeof(file_tree_string)); - i += sizeof(meta_version_string)+bencode_size_int(sizeof(file_tree_string)); - i += sizeof(name_string)+bencode_size_int(sizeof(file_tree_string)); - i += sizeof(piece_length_string)+bencode_size_int(sizeof(file_tree_string)); + i += tree_bencode_length(p->tree); + + i += sizeof(meta_version_string)+bencode_size_int(sizeof(meta_version_string)); + i += bencode_size_int(TORRENT_FILE_META_VERSION)+2; // i[INT]e + + len = strlen(p->name); + i += sizeof(name_string)+bencode_size_int(sizeof(name_string)); + i += bencode_size_int(len)+len; - i += tree_bencode_length(tree); + i += sizeof(piece_length_string)+bencode_size_int(sizeof(piece_length_string)); + i += bencode_size_int(p->piece_length)+2; // i[INT]e return i; } diff --git a/src/torrent/magnet.c b/src/torrent/magnet.c index 2a27ab6..f0eff34 100644 --- a/src/torrent/magnet.c +++ b/src/torrent/magnet.c @@ -14,7 +14,6 @@ char *torrent_magnet(struct torrent *torrent_p) { info = NULL; if((i = torrent_file_info(torrent_p,&info))<0) { goto clean; } - if(hash(info,i,infohash,crypto_hash_sha256_BYTES)<0) { goto clean; } free(info); info = NULL; diff --git a/src/torrent/piece.c b/src/torrent/piece.c index 07f6ed1..5443b1c 100644 --- a/src/torrent/piece.c +++ b/src/torrent/piece.c @@ -41,29 +41,22 @@ int torrent_file_piece_layers(FILE *fp, struct torrent *p) { } hashes = malloc(sizeof(unsigned char*)); - if(NULL==hashes) { - return -1; - } + if(NULL==hashes) { return -1; } index = 0; for(size_t i=0;ifiles.roots->size;i++) { file_p = (struct file*)p->files.roots->map[i]; if(file_p!=NULL) { hashes[index] = file_p->root; + index++; } } qsort(hashes,pieces,sizeof(unsigned char*),&piece_layer_sort); - // hashes[0] should never be NULL - if(NULL==hashes[0]) { return -1; } - - file_p = hashmap_find(p->files.roots,hashes[0],crypto_hash_sha256_BYTES); - if(NULL==file_p) { return -1; } - for(size_t i=0;ifiles.roots,hash,crypto_hash_sha256_BYTES); - if(NULL==file_p) { break; } // sorting guarantees all NULLs at end + file_p = hashmap_find(p->files.roots,hashes[i],crypto_hash_sha256_BYTES); + if(NULL==file_p) { goto clean; } if(torrent_bencode_piece_layers(fp,file_p)<0) { goto clean; } } @@ -80,5 +73,5 @@ static int piece_layer_sort(const void *p1, const void *p2) { if(NULL==p1) { return 1; } if(NULL==p2) { return -1; } - return memcmp(p1,p2,crypto_hash_sha256_BYTES); + return memcmp(*(unsigned char**)p1,*(unsigned char**)p2,crypto_hash_sha256_BYTES); } diff --git a/test/unit/test_utils.h b/test/unit/test_utils.h index 02932cc..44b407e 100644 --- a/test/unit/test_utils.h +++ b/test/unit/test_utils.h @@ -20,6 +20,7 @@ #define TEST_FILE_4 PREFIX "/.test.meta" #define TEST_FILE_4_CONTENTS ";alsikdjf;lkasdjflk\n;asjdflk\n;ajsdklfjl;aksdfjla;kj" #define TEST_FILE_5 PREFIX "/random.test" +#define TEST_FILE_6 PREFIX "/file.torrent" void clean_env(); void reset_env(); diff --git a/test/unit/torrent.tests.c b/test/unit/torrent.tests.c index 8b8300e..9c59848 100644 --- a/test/unit/torrent.tests.c +++ b/test/unit/torrent.tests.c @@ -6,6 +6,7 @@ int main(); static void torrent_add_basic_test(); static void torrent_file_info_basic_test(); static void torrent_file_path_basic_test(); +static void torrent_file_piece_layers_basic_test(); static void torrent_init_basic_test(); static void torrent_magnet_basic_test(); static void torrent_setup_example(struct torrent**); @@ -15,6 +16,7 @@ int main() { torrent_init_basic_test(); torrent_add_basic_test(); + torrent_file_piece_layers_basic_test(); torrent_magnet_basic_test(); torrent_file_info_basic_test(); torrent_file_path_basic_test(); @@ -83,10 +85,10 @@ static void torrent_file_info_basic_test() { assert(-1==torrent_file_info(NULL,NULL)); assert(-1==torrent_file_info(torrent,NULL)); - assert(212==torrent_file_info(torrent,&buf)); + assert(213==torrent_file_info(torrent,&buf)); - uint8_t expected[] = "d9:file treed4:testd0:d6:lengthi0e11:pieces root32:" "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" "ee5:test2d0:d6:lengthi0e11:pieces root32:" "\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02" "eee12:meta versioni2e4:name5:.test12:piece lengthi16384e"; - assert(memcmp(buf,expected,212)==0); + uint8_t expected[] = "d9:file treed4:testd0:d6:lengthi0e11:pieces root32:" "\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01\x01" "ee5:test2d0:d6:lengthi0e11:pieces root32:" "\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02\x02" "eee12:meta versioni2e4:name5:.test12:piece lengthi16384ee"; + assert(memcmp(buf,expected,213)==0); free(buf); @@ -115,6 +117,54 @@ static void torrent_file_path_basic_test() { free(p); } +static void hash_torrent_file(unsigned char *hash, size_t hash_len) { + uint8_t buf[16384]; + crypto_hash_sha256_state st; + FILE *fp; + size_t i; + + assert(hash_len==crypto_hash_sha256_BYTES); + + fp = fopen(TEST_FILE_6,"w"); + assert(fp!=NULL); + + assert(1==hash_init(&st)); + + while(feof(fp)!=0) { + i = fread(buf,sizeof(uint8_t),16384,fp); + if(i>0) { + assert(1==hash_update(&st,buf,i)); + } + } + + assert(0==fclose(fp)); + + assert(hash_final(&st,hash,crypto_hash_sha256_BYTES)==1); +} + +static void torrent_file_piece_layers_basic_test() { + struct torrent *torrent; + FILE *fp; + unsigned char hash[crypto_hash_sha256_BYTES]; + unsigned char expected[crypto_hash_sha256_BYTES] = {227,176,196,66,152,252,28,20,154,251,244,200,153,111,185,36,39,174,65,228,100,155,147,76,164,149,153,27,120,82,184,85}; + + fp = fopen(TEST_FILE_6,"w"); + assert(fp!=NULL); + + torrent_setup_example(&torrent); + assert(torrent_file_piece_layers(fp,torrent)==1); + + assert(0==fclose(fp)); + + hash_torrent_file(hash,crypto_hash_sha256_BYTES); + + assert(memcmp(hash,expected,crypto_hash_sha256_BYTES)==0); + + torrent_free(torrent); + + reset_env(); +} + static void torrent_init_basic_test() { struct torrent *torrent; @@ -130,13 +180,14 @@ static void torrent_init_basic_test() { static void torrent_magnet_basic_test() { struct torrent *torrent; char *p; + char expected[] = "magnet:?xt=urn:btmh:59b2020fe4275cac5c3b8ac32bdc79010c95cf0bac2fd91ced8dd071f8ef91ca&dn=" TEST_DIRECTORY; torrent_setup_example(&torrent); p = torrent_magnet(torrent); assert(p!=NULL); - assert(strcmp(p,"magnet:?xt=urn:btmh:d2cb0c8d48b492e0407e2b24ae6b9c2e542d9addf08d71eef8db7008944def9e&dn=" TEST_DIRECTORY)==0); + assert(strcmp(p,expected)==0); free(p); torrent_free(torrent);