beginning to resolve ipns addresses
This commit is contained in:
parent
b301c7e4d2
commit
378dd7c051
4 changed files with 109 additions and 3 deletions
20
cid/cid.c
20
cid/cid.c
|
@ -95,7 +95,7 @@ int ipfs_cid_protobuf_decode(unsigned char* buffer, size_t buffer_length, struct
|
||||||
* @param version the version
|
* @param version the version
|
||||||
* @param hash the multihash
|
* @param hash the multihash
|
||||||
* @param hash_length the length of the multihash in bytes
|
* @param hash_length the length of the multihash in bytes
|
||||||
* @param codec the codec to be used (NOTE: For version 0, this should be CID_PROTOBUF)
|
* @param codec the codec to be used (NOTE: For version 0, this should be CID_DAG_PROTOBUF)
|
||||||
* @returns the new Cid or NULL if there was a problem
|
* @returns the new Cid or NULL if there was a problem
|
||||||
*/
|
*/
|
||||||
struct Cid* ipfs_cid_new(int version, const unsigned char* hash, size_t hash_length, const char codec) {
|
struct Cid* ipfs_cid_new(int version, const unsigned char* hash, size_t hash_length, const char codec) {
|
||||||
|
@ -152,6 +152,24 @@ struct Cid* ipfs_cid_copy(const struct Cid* original) {
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Create a CID from an ipfs or ipns string (i.e. "/ipns/QmAb12CD..."
|
||||||
|
* @param incoming the incoming string
|
||||||
|
* @param cid the resultant Cid
|
||||||
|
* @returns true(1) on success, false(0) otherwise
|
||||||
|
*/
|
||||||
|
int ipfs_cid_decode_hash_from_ipfs_ipns_string(const char* incoming, struct Cid** cid) {
|
||||||
|
if (incoming == NULL)
|
||||||
|
return 0;
|
||||||
|
if (strstr(incoming, "/ipfs/") != incoming && strstr(incoming, "/ipns/") != incoming)
|
||||||
|
return 0;
|
||||||
|
const char* base58 = &incoming[6];
|
||||||
|
char* slash = strstr(incoming, "/");
|
||||||
|
if (slash != NULL)
|
||||||
|
slash[0] = '\0';
|
||||||
|
return ipfs_cid_decode_hash_from_base58((unsigned char*)base58, strlen(base58), cid);
|
||||||
|
}
|
||||||
|
|
||||||
/***
|
/***
|
||||||
* Fill a Cid struct based on a base 58 encoded multihash
|
* Fill a Cid struct based on a base 58 encoded multihash
|
||||||
* @param incoming the string
|
* @param incoming the string
|
||||||
|
|
|
@ -78,7 +78,7 @@ size_t ipfs_cid_protobuf_encode_size(const struct Cid* incoming);
|
||||||
* @param version the version
|
* @param version the version
|
||||||
* @param hash the multihash
|
* @param hash the multihash
|
||||||
* @param hash_length the length of the multihash in bytes
|
* @param hash_length the length of the multihash in bytes
|
||||||
* @param codec the codec to be used (NOTE: For version 0, this should be CID_PROTOBUF)
|
* @param codec the codec to be used (NOTE: For version 0, this should be CID_DAG_PROTOBUF)
|
||||||
* @returns the Cid, or NULL if there was a problem
|
* @returns the Cid, or NULL if there was a problem
|
||||||
*/
|
*/
|
||||||
struct Cid* ipfs_cid_new(int version, const unsigned char* hash, size_t hash_length, const char codec);
|
struct Cid* ipfs_cid_new(int version, const unsigned char* hash, size_t hash_length, const char codec);
|
||||||
|
@ -106,6 +106,14 @@ struct Cid* ipfs_cid_copy(const struct Cid* original);
|
||||||
*/
|
*/
|
||||||
int ipfs_cid_decode_hash_from_base58(const unsigned char* incoming, size_t incoming_length, struct Cid** cid);
|
int ipfs_cid_decode_hash_from_base58(const unsigned char* incoming, size_t incoming_length, struct Cid** cid);
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Create a CID from an ipfs or ipns string (i.e. "/ipns/QmAb12CD..."
|
||||||
|
* @param incoming the incoming string
|
||||||
|
* @param cid the resultant Cid
|
||||||
|
* @returns true(1) on success, false(0) otherwise
|
||||||
|
*/
|
||||||
|
int ipfs_cid_decode_hash_from_ipfs_ipns_string(const char* incoming, struct Cid** cid);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Turn a cid into a base 58 of a multihash of the cid hash
|
* Turn a cid into a base 58 of a multihash of the cid hash
|
||||||
* @param cid the cid to work with
|
* @param cid the cid to work with
|
||||||
|
|
80
namesys/resolver.c
Normal file
80
namesys/resolver.c
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
/**
|
||||||
|
* The opposite of publisher.c
|
||||||
|
*
|
||||||
|
* These are the resources for resolving an IPNS name, turning it into an ipfs path
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Determine if the incoming path is in ipns format
|
||||||
|
* @param path the path to check
|
||||||
|
* @returns true(1) if the path begins with "/ipns/"
|
||||||
|
*/
|
||||||
|
int is_ipns_string(char* path) {
|
||||||
|
if (path == NULL)
|
||||||
|
return 0;
|
||||||
|
if (strstr(path, "/ipns/") == path)
|
||||||
|
return 1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Resolve an IPNS name, only to its next step
|
||||||
|
* @param local_node the context
|
||||||
|
* @param path the ipns_path (i.e. "ipns/Qm12345...")
|
||||||
|
* @param results where to store the results (i.e. "ipns/Qm5678...")
|
||||||
|
* @returns true(1) on success, false(0) otherwise
|
||||||
|
*/
|
||||||
|
int ipfs_namesys_resolver_resolve_once(struct IpfsNode* local_node, const char* path, char** results) {
|
||||||
|
struct Cid* cid = NULL;
|
||||||
|
if (!ipfs_cid_decode_hash_from_ipfs_ipns_string(path, &cid)) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// look locally
|
||||||
|
struct DatastoreRecord* record;
|
||||||
|
if (local_node->repo->config->datastore->datastore_get(cid->hash, cid->hash_length, &record, local_node->repo->config->datastore)) {
|
||||||
|
// we are able to handle this locally... return the results
|
||||||
|
*results = (char*) malloc(record->value_size + 1);
|
||||||
|
memset(*results, 0, record->value_size + 1);
|
||||||
|
memcpy(*results, record->value, record->value_size);
|
||||||
|
ipfs_cid_free(cid);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: ask the network
|
||||||
|
ipfs_cid_free(cid);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resolve an IPNS name.
|
||||||
|
* NOTE: if recursive is set to false, the result could be another ipns path
|
||||||
|
* @param local_node the context
|
||||||
|
* @param path the ipns path (i.e. "/ipns/Qm12345..")
|
||||||
|
* @param recursive true to resolve until the result is not ipns, false to simply get the next step in the path
|
||||||
|
* @param result the results (i.e. "/ipfs/QmAb12CD...")
|
||||||
|
* @returns true(1) on success, false(0) otherwise
|
||||||
|
*/
|
||||||
|
int ipfs_namesys_resolver_resolve(struct IpfsNode* local_node, const char* path, int recursive, char** results) {
|
||||||
|
char* result = NULL;
|
||||||
|
char* current_path = (char*) malloc(strlen(path) + 1);
|
||||||
|
strcpy(current_path, path);
|
||||||
|
|
||||||
|
do {
|
||||||
|
// resolve the current path
|
||||||
|
if (!ipfs_namesys_resolver_resolve_once(local_node, current_path, &result)) {
|
||||||
|
libp2p_logger_error("resolver", "Resolver returned false searching for %s.\n", current_path);
|
||||||
|
free(current_path);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// result will not be NULL
|
||||||
|
free(current_path);
|
||||||
|
current_path = (char*) malloc(strlen(result)+1);
|
||||||
|
strcpy(current_path, result);
|
||||||
|
free(result);
|
||||||
|
} while(recursive && is_ipns_string(current_path));
|
||||||
|
|
||||||
|
*results = current_path;
|
||||||
|
return 1;
|
||||||
|
}
|
|
@ -260,7 +260,7 @@ int ipfs_namesys_routing_resolve_once (char **path, char *name, int depth, char
|
||||||
} else {
|
} else {
|
||||||
// Its an old style multihash record
|
// Its an old style multihash record
|
||||||
//log.Warning("Detected old style multihash record")
|
//log.Warning("Detected old style multihash record")
|
||||||
struct Cid *cid = ipfs_cid_new(0, multihash, multihash_size, CID_PROTOBUF);
|
struct Cid *cid = ipfs_cid_new(0, multihash, multihash_size, CID_DAG_PROTOBUF);
|
||||||
if (cid == NULL) {
|
if (cid == NULL) {
|
||||||
free(multihash);
|
free(multihash);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue