From f0961a247fcb35eb0f74b1b1a00217e31620dd51 Mon Sep 17 00:00:00 2001 From: John Jones Date: Sun, 16 Apr 2017 23:46:07 -0500 Subject: [PATCH] Multiaddress stability fixes --- base58.c | 1 - include/multiaddr/protoutils.h | 11 +- include/multiaddr/varhexutils.h | 11 +- multiaddr.c | 5 +- protoutils.c | 260 +++++++++++++++----------------- test_multiaddr.h | 81 ++++++++-- varhexutils.c | 59 ++++---- 7 files changed, 240 insertions(+), 188 deletions(-) diff --git a/base58.c b/base58.c index b5baf39..a3e3f90 100644 --- a/base58.c +++ b/base58.c @@ -124,7 +124,6 @@ int multiaddr_encoding_base58_decode(const char* b58, size_t base58_size, unsign * @param base58_size the size of the results buffer * @returns true(1) on success */ -//int libp2p_crypto_encoding_base58_encode(const unsigned char* binary_data, size_t binary_data_size, unsigned char* base58, size_t* base58_size) int multiaddr_encoding_base58_encode(const unsigned char* data, size_t binsz, unsigned char** b58, size_t* b58sz) { const uint8_t* bin = data; diff --git a/include/multiaddr/protoutils.h b/include/multiaddr/protoutils.h index 027bd0f..d9000a1 100644 --- a/include/multiaddr/protoutils.h +++ b/include/multiaddr/protoutils.h @@ -39,7 +39,16 @@ char * int2ip(int inputintip); */ int bytes_to_string(char** results, const uint8_t* bytes, int bytes_size); -char * address_string_to_bytes(struct Protocol * xx, const char * abc, size_t getsznow); +/** + * Convert an address string to a byte representation + * @param protocol the protocol to use + * @param incoming the byte array + * @param incoming_size the size of the byte array + * @param results the results + * @param results_size the size of the results + * @returns the results array + */ +char * address_string_to_bytes(struct Protocol *protocol, const char *incoming, size_t incoming_size, char** results, int *results_size); int string_to_bytes(uint8_t** finalbytes,size_t* realbbsize, const char * strx, size_t strsize); diff --git a/include/multiaddr/varhexutils.h b/include/multiaddr/varhexutils.h index 5d4db4e..eca3cac 100644 --- a/include/multiaddr/varhexutils.h +++ b/include/multiaddr/varhexutils.h @@ -28,10 +28,13 @@ char * Int_To_Hex(uint64_t int2hex); //VAR[binformat] TO HEX uint64_t Hex_To_Int(char * hax); -// -void vthconvert(int size, char * crrz01, uint8_t * xbuf); - -char * Var_To_Hex(int realsize, const uint8_t * TOHEXINPUT); //VAR[binformat] TO HEX +/** + * Convert binary array to array of hex values + * @param incoming the binary array + * @param incoming_size the size of the incoming array + * @returns the allocated array + */ +unsigned char *Var_To_Hex(const char *incoming, int incoming_size); /** * Turn a hex string into a byte array diff --git a/multiaddr.c b/multiaddr.c index 17ee7ed..f99ce3d 100644 --- a/multiaddr.c +++ b/multiaddr.c @@ -51,13 +51,16 @@ struct MultiAddress* multiaddress_new_from_bytes(const uint8_t* byteaddress, int multiaddress_free(out); return NULL; } - memcpy(out->bytes, byteaddress, size); out->bsize = size; + memcpy(out->bytes, byteaddress, size); if(!bytes_to_string(&out->string,byteaddress,size)==1) { multiaddress_free(out); return NULL; } + } else { + multiaddress_free(out); + return NULL; } } return out; diff --git a/protoutils.c b/protoutils.c index 5690f92..d282a90 100644 --- a/protoutils.c +++ b/protoutils.c @@ -302,87 +302,75 @@ char * int2ip(int inputintip) */ int bytes_to_string(char** buffer, const uint8_t* in_bytes, int in_bytes_size) { - *buffer = malloc(800); - char* resultzx = *buffer; - bzero(resultzx, 800); uint8_t * bytes = NULL; - int size = 0; - size = in_bytes_size; + char *results = NULL; + int size = in_bytes_size; struct ProtocolListItem* head = NULL; - load_protocols(&head); - char hex[in_bytes_size*2]; - bzero(hex,in_bytes_size*2); - strcat(hex,Var_To_Hex(size, in_bytes)); + char hex[(in_bytes_size*2)+1]; //Positioning for memory jump: int lastpos = 0; char pid[3]; + + // set up variables + load_protocols(&head); + memset(hex, 0, (in_bytes_size * 2) + 1); + char* tmp = Var_To_Hex(in_bytes, size); + memcpy(hex, tmp, in_bytes_size * 2); + free(tmp); + pid[2] = 0; + + // allocate memory for results + *buffer = malloc(800); + results = *buffer; + memset(results, 0, 800); + + //Process Hex String - //printf("FULL HEX: %s", hex); NAX: - //printf("REDO!!!!!\n"); //Stage 1 ID: - if(lastpos!=0) - { - //lastpos++; - } pid[0] = hex[lastpos]; pid[1] = hex[lastpos+1]; - pid[2] = '\0'; - //printf("pid: %s\n",pid); - if(proto_with_deccode(head, Hex_To_Int(pid))) + + int protocol_int = Hex_To_Int(pid); + struct Protocol* protocol = proto_with_deccode(head, protocol_int); + if(protocol != NULL) { -//////////Stage 2: Address - struct Protocol * PID; - PID = NULL; - PID = proto_with_deccode(head, Hex_To_Int(pid)); - if(strcmp(PID->name,"ipfs")!=0) + //////////Stage 2: Address + if(strcmp(protocol->name,"ipfs")!=0) { lastpos = lastpos+2; - char address[(PID->size/4)+1]; - bzero(address,(PID->size/4)+1); - address[(PID->size/4)]='\0'; - int x=0; - //printf("\nHEX TO DECODE: %s\n",hex); - for(int i = lastpos;i<(PID->size/4)+lastpos;i++) - { - address[x] = hex[i]; - //printf("HEX[%d]=%c\n",i,hex[i]); - x++; - } - //////////Stage 3 Process it back to string - //printf("Protocol: %s\n", PID->name); - //printf("Address : %s\n", address); - lastpos= lastpos+(PID->size/4); - //printf("lastpos: %d\n",lastpos); + char address[(protocol->size/4)+1]; + memset(address, 0, (protocol->size / 4) + 1); + memcpy(address, &hex[lastpos], protocol->size / 4); + //////////Stage 3 Process it back to string + lastpos= lastpos+(protocol->size/4); - //////////Address: + //////////Address: //Keeping Valgrind happy char name[30]; bzero(name,30); - strcpy(name, PID->name); + strcpy(name, protocol->name); // - strcat(resultzx, "/"); - strcat(resultzx, name); - strcat(resultzx, "/"); + strcat(results, "/"); + strcat(results, name); + strcat(results, "/"); if(strcmp(name, "ip4")==0) { - strcat(resultzx,int2ip(Hex_To_Int(address))); + strcat(results,int2ip(Hex_To_Int(address))); } else if(strcmp(name, "tcp")==0) { char a[5]; sprintf(a,"%lu",Hex_To_Int(address)); - strcat(resultzx,a); + strcat(results,a); } else if(strcmp(name, "udp")==0) { char a[5]; sprintf(a,"%lu",Hex_To_Int(address)); - strcat(resultzx,a); + strcat(results,a); } - //printf("Address(hex):%s\n",address); - //printf("TESTING: %s\n",resultzx); - /////////////Done processing this, move to next if there is more. + /////////////Done processing this, move to next if there is more. if(lastposname); - strcat(resultzx, "/"); - strcat(resultzx, rezultat); + strcat(results, "/"); + strcat(results, protocol->name); + strcat(results, "/"); + strcat(results, b58); } } - strcat(resultzx, "/"); + strcat(results, "/"); unload_protocols(head); return 1; - } // -char * address_string_to_bytes(struct Protocol * xx, const char * abc,size_t getsznow) +/** + * Convert an address string to a byte representation + * @param protocol the protocol to use + * @param incoming the byte array + * @param incoming_size the size of the byte array + * @param results the results + * @param results_size the size of the results + * @returns the results array + */ +char* address_string_to_bytes(struct Protocol * protocol, const char *incoming, size_t incoming_size, char** results, int* results_size) { static char astb__stringy[800] = "\0"; - bzero(astb__stringy,800); + memset(astb__stringy, 0, 800); + int code = 0; - code = xx->deccode; + code = protocol->deccode; + switch(code) { case 4://IPv4 { char testip[16] = "\0"; bzero(testip,16); - strcpy(testip,abc); + strcpy(testip,incoming); if(is_valid_ipv4(testip)==1) { - uint64_t iip = ip2int(abc); + uint64_t iip = ip2int(incoming); strcpy(astb__stringy,Int_To_Hex(iip)); - xx = NULL; - return astb__stringy; + protocol = NULL; + *results = malloc(strlen(astb__stringy)); + memcpy(*results, astb__stringy, strlen(astb__stringy)); + *results_size = strlen(astb__stringy); + return *results; } else { @@ -476,11 +463,11 @@ char * address_string_to_bytes(struct Protocol * xx, const char * abc,size_t get } case 6: //Tcp { - if(atoi(abc)<65536&&atoi(abc)>0) + if(atoi(incoming)<65536&&atoi(incoming)>0) { static char himm_woot[5] = "\0"; bzero(himm_woot, 5); - strcpy(himm_woot, Int_To_Hex(atoi(abc))); + strcpy(himm_woot, Int_To_Hex(atoi(incoming))); if(himm_woot[2] == '\0') {//manual switch char swap0='0'; @@ -504,7 +491,10 @@ char * address_string_to_bytes(struct Protocol * xx, const char * abc,size_t get himm_woot[3] = swap3; } himm_woot[4]='\0'; - return himm_woot; + *results = malloc(5); + *results_size = 5; + memcpy(*results, himm_woot, 5); + return *results; } else { @@ -514,11 +504,11 @@ char * address_string_to_bytes(struct Protocol * xx, const char * abc,size_t get } case 17: //Udp { - if(atoi(abc)<65536&&atoi(abc)>0) + if(atoi(incoming)<65536&&atoi(incoming)>0) { static char himm_woot2[5] = "\0"; bzero(himm_woot2, 5); - strcpy(himm_woot2, Int_To_Hex(atoi(abc))); + strcpy(himm_woot2, Int_To_Hex(atoi(incoming))); if(himm_woot2[2] == '\0') {//Manual Switch2be char swap0='0'; @@ -542,7 +532,10 @@ char * address_string_to_bytes(struct Protocol * xx, const char * abc,size_t get himm_woot2[3] = swap3; } himm_woot2[4]='\0'; - return himm_woot2; + *results = malloc(5); + *results_size = 5; + memcpy(*results, himm_woot2, 5); + return *results; } else { @@ -553,98 +546,82 @@ char * address_string_to_bytes(struct Protocol * xx, const char * abc,size_t get case 33://dccp { return "ERR"; - break; } case 132://sctp { return "ERR"; - break; } case 301://udt { return "ERR"; - break; } case 302://utp { return "ERR"; - break; } case 42://IPFS - !!! { - char * x_data = NULL; - x_data = (char*) abc; - size_t x_data_length = strlen(x_data); - size_t result_buffer_length = multiaddr_encoding_base58_decode_max_size((unsigned char*)x_data); + // decode the base58 to bytes + char * incoming_copy = NULL; + incoming_copy = (char*)incoming; + size_t incoming_copy_size = strlen(incoming_copy); + size_t result_buffer_length = multiaddr_encoding_base58_decode_max_size((unsigned char*)incoming_copy); unsigned char result_buffer[result_buffer_length]; unsigned char* ptr_to_result = result_buffer; memset(result_buffer, 0, result_buffer_length); // now get the decoded address - - int return_value = multiaddr_encoding_base58_decode(x_data, x_data_length, &ptr_to_result, &result_buffer_length); + int return_value = multiaddr_encoding_base58_decode(incoming_copy, incoming_copy_size, &ptr_to_result, &result_buffer_length); if (return_value == 0) { return "ERR"; } + // throw everything in a hex string so we can debug the results - static char returning_result[300]; - bzero(returning_result,300); - char ADDR_ENCODED[300]; - bzero(ADDR_ENCODED,300); + char addr_encoded[300]; + memset(addr_encoded, 0, 300); int ilen = 0; - bzero(returning_result,300); for(int i = 0; i < result_buffer_length; i++) { // get the char so we can see it in the debugger - unsigned char c = ptr_to_result[i]; char miu[3]; - bzero(miu, 3); - miu[2] = '\0'; - sprintf(miu,"%02x", c); - - strcat(ADDR_ENCODED, miu); + sprintf(miu,"%02x", ptr_to_result[i]); + strcat(addr_encoded, miu); } - ilen = strlen(ADDR_ENCODED); + ilen = strlen(addr_encoded); char prefixed[3]; + memset(prefixed, 0, 3); strcpy(prefixed,Num_To_HexVar_32(ilen)); - prefixed[2] = '\0'; - strcat(returning_result, prefixed); - strcat(returning_result, ADDR_ENCODED); - //printf("ADDRESS: %s\nSIZEADDR: %d\n",ADDR_ENCODED,ilen); - //printf("NOW DECODED VARINT: %d", HexVar_To_Num_32(prefixed)); - return returning_result; - break; + *results_size = ilen + 3; + *results = malloc(*results_size); + memset(*results, 0, *results_size); + strcat(*results, prefixed); // 2 bytes + strcat(*results, addr_encoded); // ilen bytes + null terminator + return *results; } case 480://http { return "ERR"; - break; } case 443://https { return "ERR"; - break; } case 477://ws { return "ERR"; - break; } case 444://onion { return "ERR"; - break; } case 275://libp2p-webrtc-star { return "ERR"; - break; } default: { printf("NO SUCH PROTOCOL!\n"); return "ERR"; - break; } } } @@ -690,10 +667,9 @@ int string_to_bytes(uint8_t** finalbytes, size_t* realbbsize, const char* strx, { if(firstorsecond==1)//This is the Protocol { - if(proto_with_name(head, wp)) + protx = proto_with_name(head, wp); + if(protx != NULL) { - protx=proto_with_name(head, wp); - //printf("PROTOCOL: %s\n",protx->name); strcat(processed, Int_To_Hex(protx->deccode)); firstorsecond=2;//Since the next word will be an address } @@ -706,16 +682,18 @@ int string_to_bytes(uint8_t** finalbytes, size_t* realbbsize, const char* strx, } else//This is the address { - //printf("ADDRESS: %s\n",wp); - if(address_string_to_bytes(protx, wp,strlen(wp)) == "ERR") + char* s_to_b = NULL; + int s_to_b_size = 0; + if(address_string_to_bytes(protx, wp,strlen(wp), &s_to_b, &s_to_b_size) == "ERR") { malf = 1; - //printf("\n\nTRIGGERED!!!!!!!!!!!!!!!!!!!!!!!\n\n"); } else { - strcat(processed,address_string_to_bytes(protx, wp,strlen(wp))); - //printf("Addressinbytes: %s\n",address_string_to_bytes(protx, wp,strlen(wp))); + int temp_size = strlen(processed); + strncat(processed, s_to_b, s_to_b_size); + processed[temp_size + s_to_b_size] = 0; + free(s_to_b); } protx=NULL;//Since right now it doesn't need that assignment anymore. firstorsecond=1;//Since the next word will be an protocol diff --git a/test_multiaddr.h b/test_multiaddr.h index 0867856..613fef2 100644 --- a/test_multiaddr.h +++ b/test_multiaddr.h @@ -1,6 +1,7 @@ #pragma once #include "multiaddr/multiaddr.h" +#include "multiaddr/varhexutils.h" int test_new_from_string() { struct MultiAddress* a = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/8080/"); @@ -19,22 +20,30 @@ int test_full() { printf("INITIAL: %s\n",addrstr); struct MultiAddress* a; a= multiaddress_new_from_string(addrstr); - printf("TEST BYTES: %s\n",Var_To_Hex(a->bsize, a->bytes)); + unsigned char* tmp = Var_To_Hex(a->bytes, a->bsize); + printf("TEST BYTES: %s\n", tmp); + free(tmp); //Remember, Decapsulation happens from right to left, never in reverse! printf("A STRING:%s\n",a->string); multiaddress_encapsulate(a,"/udp/3333/"); printf("A STRING ENCAPSULATED:%s\n",a->string); - printf("TEST BYTES: %s\n",Var_To_Hex(a->bsize, a->bytes)); + tmp = Var_To_Hex(a->bytes, a->bsize); + printf("TEST BYTES: %s\n", tmp); + free(tmp); multiaddress_decapsulate(a,"udp"); printf("A STRING DECAPSULATED UDP:%s\n",a->string); - printf("TEST BYTES: %s\n",Var_To_Hex(a->bsize, a->bytes)); + tmp = Var_To_Hex(a->bytes, a->bsize); + printf("TEST BYTES: %s\n", tmp); + free(tmp); multiaddress_encapsulate(a,"/udp/3333/"); printf("A STRING ENCAPSULATED UDP: %s\n",a->string); multiaddress_encapsulate(a,"/ipfs/QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG"); printf("A STRING ENCAPSULATED IPFS:%s\n",a->string); - printf("TEST BYTES: %s\n",Var_To_Hex(a->bsize, a->bytes)); + tmp = Var_To_Hex(a->bytes, a->bsize); + printf("TEST BYTES: %s\n", tmp); + free(tmp); printf("TEST BYTE SIZE: %lu\n",a->bsize); struct MultiAddress* beta; @@ -69,6 +78,7 @@ int test_int_to_hex() { } int test_multiaddr_utils() { + int retVal = 0; struct MultiAddress* addr = multiaddress_new_from_string("/ip4/127.0.0.1/tcp/4001/"); if (!multiaddress_is_ip(addr)) { fprintf(stderr, "The address should be an IP\n"); @@ -78,28 +88,36 @@ int test_multiaddr_utils() { multiaddress_get_ip_address(addr, &ip); if (ip == NULL) { fprintf(stderr, "get_ip_address returned NULL\n"); - return 0; + goto exit; } if(strcmp(ip, "127.0.0.1") != 0) { fprintf(stderr, "ip addresses are not equal\n"); - return 0; + goto exit; } int port = multiaddress_get_ip_port(addr); if (port != 4001) { fprintf(stderr, "port incorrect. %d was returned instead of %d\n", port, 4001); - return 0; + goto exit; } - return 1; + + retVal = 1; + exit: + if (ip != NULL) + free(ip); + if (addr != NULL) + multiaddress_free(addr); + return retVal; } int test_multiaddr_peer_id() { - char* orig_address = "QmKhhKHkjhkjhKjhiuhKJh"; + char* orig_address = "QmYwAPJzv5CZsnA625s3Xf2nemtYgPpHdWEz79ojWnPbdG"; char full_string[255]; char* result = NULL; + char* bytes = NULL; int retVal = 0; - struct MultiAddress* addr; + struct MultiAddress *addr = NULL, *addr2 = NULL; - sprintf(full_string, "/ip4/127.0.0.1/tcp/4001/ipfs/%s", orig_address); + sprintf(full_string, "/ip4/127.0.0.1/tcp/4001/ipfs/%s/", orig_address); addr = multiaddress_new_from_string(full_string); @@ -108,10 +126,51 @@ int test_multiaddr_peer_id() { if (result == NULL || strncmp(result, orig_address, strlen(orig_address)) != 0) goto exit; + result = NULL; + + // switch to bytes and back again to verify the peer id follows... + + // 1. display the original bytes + result = Var_To_Hex(addr->bytes, addr->bsize); + fprintf(stderr, "Original Bytes: %s\n", result); + free(result); + result = NULL; + + // make a new MultiAddress from bytes + bytes = malloc(addr->bsize); + memcpy(bytes, addr->bytes, addr->bsize); + addr2 = multiaddress_new_from_bytes(bytes, addr->bsize); + + free(bytes); + bytes = NULL; + + // 2. Display the resultant bytes + result = Var_To_Hex(addr2->bytes, addr2->bsize); + fprintf(stderr, "New Bytes: %s\n", result); + free(result); + result = NULL; + + if (strcmp(full_string, addr2->string) != 0) { + fprintf(stderr, "Original string was %s but new string is %s\n", full_string, addr2->string); + goto exit; + } + + int port = multiaddress_get_ip_port(addr2); + if (port != 4001) { + fprintf(stderr, "Original string had port 4001, but now reporting %d\n", port); + goto exit; + } + retVal = 1; exit: if (addr != NULL) multiaddress_free(addr); + if (addr2 != NULL) + multiaddress_free(addr2); + if (result != NULL) + free(result); + if (bytes != NULL) + free(bytes); return retVal; } diff --git a/varhexutils.c b/varhexutils.c index dea41f6..cec9c08 100644 --- a/varhexutils.c +++ b/varhexutils.c @@ -77,41 +77,42 @@ uint64_t Hex_To_Int(char * hax) } return val; } -// -void vthconvert(int size, char * crrz01, const uint8_t * xbuf) -{ - uint8_t buf[400]; - bzero(buf,400); - //fixing the buf - for(int cz=0; cz