123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397 |
- #include <string.h>
- #include <sys/socket.h>
- #include "multiaddr/varhexutils.h"
- #include "multiaddr/varint.h"
- #include "multiaddr/protocols.h"
- #include "multiaddr/protoutils.h"
- #include "multiaddr/multiaddr.h"
- int strpos(char *haystack, char *needle)
- {
- char *p = strstr(haystack, needle);
- if (p)
- {
- return p - haystack;
- }
- else
- {
- return -1; // Not found = -1.
- }
- }
- /**
- * Construct a new MultiAddress struct
- * @returns an empty MultiAddress struct
- */
- struct MultiAddress* multiaddress_new() {
- struct MultiAddress* out = (struct MultiAddress*)malloc(sizeof(struct MultiAddress));
- if (out != NULL) {
- out->bsize = 0;
- out->bytes = NULL;
- out->string = NULL;
- }
- return out;
- }
- /**
- * construct a new MultiAddress from bytes
- * @param byteaddress the byte array
- * @param size the size of the byte array
- * @returns a new MultiAddress struct filled in, or NULL on error
- */
- struct MultiAddress* multiaddress_new_from_bytes(const uint8_t* byteaddress, int size)//Construct new address from bytes
- {
- struct MultiAddress* out = multiaddress_new();
- if (out != NULL) {
- if(byteaddress!=NULL)
- {
- out->bytes = malloc(size);
- if (out->bytes == NULL) {
- multiaddress_free(out);
- return NULL;
- }
- out->bsize = size;
- memcpy(out->bytes, byteaddress, size);
- if(!bytes_to_string(&out->string,byteaddress,size))
- {
- multiaddress_free(out);
- return NULL;
- }
- } else {
- multiaddress_free(out);
- return NULL;
- }
- }
- return out;
- }
- struct MultiAddress* multiaddress_new_from_string(const char* straddress)//Construct new address from string
- {
- struct MultiAddress* out = multiaddress_new();
- if (out != NULL) {
- out->string = malloc(strlen(straddress) + 1);
- if (out->string == NULL) {
- multiaddress_free(out);
- return NULL;
- }
- strcpy(out->string, straddress);
- if (string_to_bytes(&(out->bytes), &out->bsize, out->string, strlen(out->string)) == 0 )
- {
- multiaddress_free(out);
- return NULL;
- }
- }
- return out;
- }
- int multiaddress_is_ip(const struct MultiAddress* in) {
- if (in->bytes > 0) {
- int byte = in->bytes[0];
- if (byte == 4 || byte == 41)
- return 1;
- }
- return 0;
- }
- int multiaddress_is_ip4(const struct MultiAddress* in) {
- return in->bytes[0] == 4;
- }
- int multiaddress_is_ip6(const struct MultiAddress* in) {
- return in->bytes[0] == 41;
- }
- int multiaddress_get_ip_family(const struct MultiAddress* in) {
- if (in->bytes[0] == 4)
- return AF_INET;
- if (in->bytes[0] == 41)
- return AF_INET6;
- return 0;
- }
- /***
- * Pulls the textual representation of the IP address from a multihash
- * @param in the multihash to parse
- * @param ip where to put the ip address
- * @returns true(1) on success, otherwise 0
- */
- int multiaddress_get_ip_address(const struct MultiAddress* in, char** ip) {
- // the incoming address is not what was expected
- if (strncmp(in->string, "/ip4/", 5) != 0 && strncmp(in->string, "/ip6/", 5) != 0)
- return 0;
- if (strstr(in->string, "/tcp/") == NULL && strstr(in->string, "/udp/") == NULL)
- return 0;
- // ip
- char* str = malloc(strlen(in->string));
- if (str == NULL)
- return 0;
- strcpy(str, &in->string[5]); // gets rid of /ip4/
- char* pos = strchr(str, '/');
- pos[0] = 0;
- *ip = malloc(strlen(str) + 1);
- strcpy(*ip, str);
- free(str);
- return 1;
- }
- /***
- * Pulls the IP port from a multiaddress
- * @param in the multiaddress
- * @param port where to put the port
- * @returns the port, or a negative number for an error
- */
- int multiaddress_get_ip_port(const struct MultiAddress* in) {
- char* ptr = strstr(in->string, "/tcp/");
- if (ptr == NULL)
- ptr = strstr(in->string, "/udp/");
- if (ptr == NULL)
- return -1;
- ptr += 5;
- char* end_ptr = strstr(ptr, "/");
- if (end_ptr == NULL) {
- return atoi(ptr);
- }
- char str[end_ptr - ptr + 1];
- memcpy(str, ptr, end_ptr - ptr);
- str[end_ptr-ptr] = '\0';
- return atoi(str);
- }
- char* multiaddress_get_peer_id(const struct MultiAddress* in) {
- char* result = NULL;
- int str_len = 0;
- char* slash = NULL;
- char* ptr = NULL;
- ptr = strstr(in->string, "/ipfs/");
- if (ptr != NULL && ptr[6] != 0) {
- ptr += 6;
- str_len = strlen(ptr);
- slash = strchr(ptr, '/');
- if (slash != NULL) {
- str_len = slash - ptr;
- }
- if (str_len > 0) {
- result = malloc(str_len + 1);
- if (result != NULL) {
- memset(result, 0, str_len + 1);
- memcpy(result, ptr, str_len);
- }
- }
- }
- return result;
- }
- void multiaddress_free(struct MultiAddress* in) {
- if (in != NULL) {
- if (in->bytes != NULL)
- free(in->bytes);
- if (in->string != NULL)
- free(in->string);
- free(in);
- in = NULL;
- }
- }
- /**
- * Copy a multiaddress from one memory location to another
- * @param in the source
- * @returns the new struct MultiAddress or NULL if there was a problem (i.e. out of memory)
- */
- struct MultiAddress* multiaddress_copy(const struct MultiAddress* in) {
- struct MultiAddress* out = NULL;
- if (in != NULL) {
- out = (struct MultiAddress*)malloc(sizeof(struct MultiAddress));
- if (out != NULL) {
- if (in->bsize > 0) {
- out->bytes = malloc(in->bsize);
- if (out->bytes == NULL) {
- free(out);
- return NULL;
- }
- out->bsize = in->bsize;
- memcpy(out->bytes, in->bytes, out->bsize);
- } // bytes need to be copied
- if (in->string != NULL) {
- out->string = malloc(strlen(in->string) + 1);
- if (out->string == NULL) {
- if (out->bsize > 0)
- free(out->bytes);
- free(out);
- return NULL;
- }
- strcpy(out->string, in->string);
- } // string needs to be copied
- } // structure allocated
- } // good parameters
- return out;
- }
- /**
- * Put a string into the MultiAddress and recalculate the bytes
- * @param result the struct
- * @param string the new string
- */
- int multiaddress_encapsulate(struct MultiAddress* result, char* string)
- {
- if(result != NULL && string != NULL)
- {
- // remove the old values
- if (result->bytes != NULL)
- free(result->bytes);
- result->bytes = NULL;
- result->bsize = 0;
- char * exstr;
- if(string[0] == '/')
- {
- exstr = (char *) malloc(strlen(result->string)+1);
- }
- else
- {
- exstr = (char *) malloc(strlen(result->string));
- }
- strcpy(exstr, result->string);
- free(result->string);
- // insert the new values
- result->string = malloc(strlen(string) + strlen(exstr) + 1);
- if (result->string == NULL) {
- multiaddress_free(result);
- return 0;
- }
- strcpy(result->string, exstr);
- free(exstr);
- if(string[0] == '/')
- {
- strcat(result->string, string+1);
- }
- else
- {
- strcat(result->string, string);
- }
- if(string_to_bytes(&result->bytes, &result->bsize, result->string, strlen(result->string)+1) == 0)
- {
- multiaddress_free(result);
- return 0;
- }
- } else {
- return 0;
- }
- return 1;
- }
- /**
- * Find scri and remove it from the resultant value
- * (ie /ip4/127.0.0.1/tcp/4001 becomes ip4/127.0.0.1 when you call decapsulate(addr, "/tcp")
- * @param result the address to work with
- * @param srci the string to look for
- */
- int multiaddress_decapsulate(struct MultiAddress * result, char * srci)
- {
- if(result!=NULL && srci!=NULL)
- {
- char * procstr = NULL;
- procstr = result->string;
- int i=0;
- int sz=strlen(procstr);
- char * src = NULL;
- src=srci;
- // change slash to space
- for(i=0;i<sz;i++)
- {
- if(procstr[i] == '/')
- {
- procstr[i]=' ';
- }
- }
- int pos=-1;
- pos=strpos(procstr,src);
- if(pos!=-1)
- {
- // fill rest with 0s
- for(i=pos;i<sz;i++)
- {
- procstr[i] = '\0';
- }
- // replace space with slash
- for(i=0;i<sz;i++)
- {
- if(procstr[i] == ' ')
- {
- procstr[i] = '/';
- }
- }
- //Bytes update
- if (result->bytes != NULL)
- free(result->bytes);
- result->bytes = NULL;
- result->bsize = 0;
- if(string_to_bytes(&result->bytes, &result->bsize, result->string, strlen(result->string)+1) == 0)
- {
- multiaddress_free(result);
- return 0;
- }
- return 1;
- }
- else
- {
- return 0;
- }
- return 0;
- }
- else
- {
- return 0;
- }
- }
- /**
- * Check to see how these two addresses compare
- * @param a side A
- * @param b side B
- * @returns <0 if B > A; >0 if A > B; 0 if A == B
- */
- int multiaddress_compare(const struct MultiAddress* a, const struct MultiAddress* b) {
- if (a == NULL && b == NULL)
- return 0;
- if (a == NULL && b != NULL)
- return -1;
- if (a != NULL && b == NULL)
- return 1;
- int total = b->bsize - a->bsize;
- if (total != 0)
- return total;
- for(size_t i = 0; i < b->bsize; i++) {
- total = b->bytes[i] - a->bytes[i];
- if (total != 0)
- return total;
- }
- return 0;
- }
- /**
- * Check to see how these two addresses compare, ignoring IP address,
- * only looking at the first /ipfs/ID hash
- * @param a side A
- * @param b side B
- * @returns <0 if B > A; >0 if A > B; 0 if A == B
- */
- int multiaddress_compare_id(const struct MultiAddress* a, const struct MultiAddress* b) {
- char* a_id = multiaddress_get_peer_id(a);
- char* b_id = multiaddress_get_peer_id(b);
- if (a_id == NULL && b_id == NULL)
- return 0;
- if (a_id == NULL && b_id != NULL)
- return -1;
- if (a_id != NULL && b_id == NULL)
- return 1;
- int retVal = strcmp(a_id, b_id);
- if (a_id != NULL)
- free(a_id);
- if (b_id != NULL)
- free(b_id);
- return retVal;
- }
|