Merge branch 'master' of https://github.com/kenCode-de/c-ipfs
This commit is contained in:
commit
f8cdaf0a97
8 changed files with 198 additions and 53 deletions
|
@ -1,14 +1,19 @@
|
||||||
#ifndef IPNS_NAMESYS_PB_H
|
#ifndef IPNS_NAMESYS_PB_H
|
||||||
#define IPNS_NAMESYS_PB_H
|
#define IPNS_NAMESYS_PB_H
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef int IpnsEntry_ValidityType;
|
typedef int32_t IpnsEntry_ValidityType;
|
||||||
|
|
||||||
struct ipns_entry {
|
struct ipns_entry {
|
||||||
// TODO
|
char *value;
|
||||||
struct routingResolver *cache;
|
char *signature;
|
||||||
struct stime *eol;
|
int32_t *validityType;
|
||||||
|
char *validity;
|
||||||
|
uint64_t *sequence;
|
||||||
|
uint64_t *ttl;
|
||||||
|
struct routingResolver *cache; // cache and eol should be the last items.
|
||||||
|
struct timespec *eol;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct namesys_pb {
|
struct namesys_pb {
|
||||||
// TODO
|
// TODO
|
||||||
struct ipns_entry *IpnsEntry;
|
struct ipns_entry *IpnsEntry;
|
||||||
|
@ -23,8 +28,9 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
int IpnsEntry_ValidityType_value (char *s);
|
int IpnsEntry_ValidityType_value (char *s);
|
||||||
|
struct ipns_entry* ipfs_namesys_pb_new_ipns_entry ();
|
||||||
char* ipfs_namesys_pb_get_validity (struct ipns_entry*);
|
char* ipfs_namesys_pb_get_validity (struct ipns_entry*);
|
||||||
char* ipfs_ipns_entry_data_for_sig(struct ipns_entry*);
|
char* ipns_entry_data_for_sig(struct ipns_entry*);
|
||||||
char* ipfs_ipns_entry_get_signature(struct ipns_entry*);
|
char* ipfs_ipns_entry_get_signature(struct ipns_entry*);
|
||||||
int ipfs_namesys_pb_get_value (char**, struct ipns_entry*);
|
int ipfs_namesys_pb_get_value (char**, struct ipns_entry*);
|
||||||
IpnsEntry_ValidityType ipfs_namesys_pb_get_validity_type (struct ipns_entry*);
|
IpnsEntry_ValidityType ipfs_namesys_pb_get_validity_type (struct ipns_entry*);
|
||||||
|
|
9
include/ipfs/namesys/publisher.h
Normal file
9
include/ipfs/namesys/publisher.h
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
#ifndef IPFS_PUBLISHER_H
|
||||||
|
#define IPFS_PUBLISHER_H
|
||||||
|
char* ipns_entry_data_for_sig (struct ipns_entry *entry);
|
||||||
|
int ipns_selector_func (int *idx, struct ipns_entry ***recs, char *k, char **vals);
|
||||||
|
int ipns_select_record (int *idx, struct ipns_entry **recs, char **vals);
|
||||||
|
// ipns_validate_ipns_record implements ValidatorFunc and verifies that the
|
||||||
|
// given 'val' is an IpnsEntry and that that entry is valid.
|
||||||
|
int ipns_validate_ipns_record (char *k, char *val);
|
||||||
|
#endif // IPFS_PUBLISHER_H
|
|
@ -10,7 +10,7 @@
|
||||||
struct cacheEntry {
|
struct cacheEntry {
|
||||||
char *key;
|
char *key;
|
||||||
char *value;
|
char *value;
|
||||||
struct stime eol;
|
struct timespec eol;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct routingResolver {
|
struct routingResolver {
|
||||||
|
@ -29,7 +29,8 @@
|
||||||
// ipfs_namesys_routing_resolve_once implements resolver. Uses the IPFS
|
// ipfs_namesys_routing_resolve_once implements resolver. Uses the IPFS
|
||||||
// routing system to resolve SFS-like names.
|
// routing system to resolve SFS-like names.
|
||||||
int ipfs_namesys_routing_resolve_once (char **path, char *name, int depth, char *prefix, struct namesys_pb *pb);
|
int ipfs_namesys_routing_resolve_once (char **path, char *name, int depth, char *prefix, struct namesys_pb *pb);
|
||||||
int ipfs_namesys_routing_check_EOL (struct stime *st, struct namesys_pb *pb);
|
int ipfs_namesys_routing_check_EOL (struct timespec *ts, struct namesys_pb *pb);
|
||||||
|
|
||||||
int ipfs_namesys_routing_get_value (char*, char*);
|
int ipfs_namesys_routing_get_value (char*, char*);
|
||||||
int ipfs_namesys_routing_getpublic_key (char*, struct MultiHash*);
|
int ipfs_namesys_routing_getpublic_key (char*, struct MultiHash*);
|
||||||
#endif // IPNS_NAMESYS_ROUTING_H
|
#endif // IPNS_NAMESYS_ROUTING_H
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
#ifndef IPFS_TIME_H
|
#ifndef IPFS_TIME_H
|
||||||
#define IPFS_TIME_H
|
#define IPFS_TIME_H
|
||||||
|
#ifndef __USE_XOPEN
|
||||||
|
#define __USE_XOPEN
|
||||||
|
#endif // __USE_XOPEN
|
||||||
|
|
||||||
struct stime {
|
#ifndef __USE_ISOC11
|
||||||
time_t t;
|
#define __USE_ISOC11
|
||||||
struct timespec ts;
|
#endif // __USE_ISOC11
|
||||||
};
|
|
||||||
|
|
||||||
int get_gmttime(struct stime *st);
|
#include <time.h>
|
||||||
int ipfs_util_time_parse_RFC3339 (struct stime *st, char *s);
|
|
||||||
char *ipfs_util_time_format_RFC3339 (struct stime *st);
|
int ipfs_util_time_parse_RFC3339 (struct timespec *ts, char *s);
|
||||||
|
char *ipfs_util_time_format_RFC3339 (struct timespec *ts);
|
||||||
#endif // IPFS_TIME_H
|
#endif // IPFS_TIME_H
|
||||||
|
|
22
namesys/pb.c
22
namesys/pb.c
|
@ -1,4 +1,5 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "ipfs/namesys/routing.h"
|
||||||
#include "ipfs/namesys/pb.h"
|
#include "ipfs/namesys/pb.h"
|
||||||
|
|
||||||
int IpnsEntry_ValidityType_value (char *s)
|
int IpnsEntry_ValidityType_value (char *s)
|
||||||
|
@ -17,3 +18,24 @@ int IpnsEntry_ValidityType_value (char *s)
|
||||||
|
|
||||||
return -1; // not found.
|
return -1; // not found.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ipns_entry* ipfs_namesys_pb_new_ipns_entry ()
|
||||||
|
{
|
||||||
|
return calloc(1, sizeof (struct ipns_entry));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ipfs_namesys_ipnsentry_reset (struct ipns_entry *m)
|
||||||
|
{
|
||||||
|
if (m) {
|
||||||
|
// ipns_entry is an struct of pointers,
|
||||||
|
// so we can access as an array of pointers.
|
||||||
|
char **a = (char **)m;
|
||||||
|
int i, l = (sizeof (struct ipns_entry) / sizeof (void*)) - 2; // avoid last 2 pointers, cache and eol.
|
||||||
|
for (i = 0 ; i < l ; i++) {
|
||||||
|
if (a[i]) {
|
||||||
|
free (a[i]); // free allocated pointers,
|
||||||
|
a[i] = NULL; // and mark as free.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
125
namesys/publisher.c
Normal file
125
namesys/publisher.c
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include "ipfs/errs.h"
|
||||||
|
#include "ipfs/util/time.h"
|
||||||
|
#include "ipfs/namesys/pb.h"
|
||||||
|
#include "ipfs/namesys/publisher.h"
|
||||||
|
|
||||||
|
char* ipns_entry_data_for_sig (struct ipns_entry *entry)
|
||||||
|
{
|
||||||
|
char *ret;
|
||||||
|
|
||||||
|
if (!entry || !entry->value || !entry->validity) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
ret = calloc (1, strlen(entry->value) + strlen (entry->validity) + sizeof(IpnsEntry_ValidityType) + 1);
|
||||||
|
if (ret) {
|
||||||
|
strcpy(ret, entry->value);
|
||||||
|
strcat(ret, entry->validity);
|
||||||
|
if (entry->validityType) {
|
||||||
|
memcpy(ret+strlen(entry->value)+strlen(entry->validity), entry->validityType, sizeof(IpnsEntry_ValidityType));
|
||||||
|
} else {
|
||||||
|
memcpy(ret+strlen(entry->value)+strlen(entry->validity), &IpnsEntry_EOL, sizeof(IpnsEntry_ValidityType));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipns_selector_func (int *idx, struct ipns_entry ***recs, char *k, char **vals)
|
||||||
|
{
|
||||||
|
int err, i, c;
|
||||||
|
|
||||||
|
if (!idx || !recs || !k || !vals) {
|
||||||
|
return ErrInvalidParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (c = 0 ; vals[c] ; c++); // count array
|
||||||
|
|
||||||
|
*recs = calloc(c+1, sizeof (void*)); // allocate return array.
|
||||||
|
if (!*recs) {
|
||||||
|
return ErrAllocFailed;
|
||||||
|
}
|
||||||
|
for (i = 0 ; i < c ; i++) {
|
||||||
|
*recs[i] = calloc(1, sizeof (struct ipns_entry)); // alloc every record
|
||||||
|
if (!*recs[i]) {
|
||||||
|
return ErrAllocFailed;
|
||||||
|
}
|
||||||
|
//err = proto.Unmarshal(vals[i], *recs[i]); // and decode.
|
||||||
|
if (err) {
|
||||||
|
ipfs_namesys_ipnsentry_reset (*recs[i]); // make sure record is empty.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return ipns_select_record(idx, *recs, vals);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ipns_select_record (int *idx, struct ipns_entry **recs, char **vals)
|
||||||
|
{
|
||||||
|
int err, i, best_i = -1, best_seq = 0;
|
||||||
|
struct timespec rt, bestt;
|
||||||
|
|
||||||
|
if (!idx || !recs || !vals) {
|
||||||
|
return ErrInvalidParam;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0 ; recs[i] ; i++) {
|
||||||
|
if (!(recs[i]->sequence) || *(recs[i]->sequence) < best_seq) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (best_i == -1 || *(recs[i]->sequence) > best_seq) {
|
||||||
|
best_seq = *(recs[i]->sequence);
|
||||||
|
best_i = i;
|
||||||
|
} else if (*(recs[i]->sequence) == best_seq) {
|
||||||
|
err = ipfs_util_time_parse_RFC3339 (&rt, ipfs_namesys_pb_get_validity (recs[i]));
|
||||||
|
if (err) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
err = ipfs_util_time_parse_RFC3339 (&bestt, ipfs_namesys_pb_get_validity (recs[best_i]));
|
||||||
|
if (err) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (rt.tv_sec > bestt.tv_sec || (rt.tv_sec == bestt.tv_sec && rt.tv_nsec > bestt.tv_nsec)) {
|
||||||
|
best_i = i;
|
||||||
|
} else if (rt.tv_sec == bestt.tv_sec && rt.tv_nsec == bestt.tv_nsec) {
|
||||||
|
if (memcmp(vals[i], vals[best_i], strlen(vals[best_i])) > 0) { // FIXME: strlen?
|
||||||
|
best_i = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (best_i == -1) {
|
||||||
|
return ErrNoRecord;
|
||||||
|
}
|
||||||
|
*idx = best_i;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ipns_validate_ipns_record implements ValidatorFunc and verifies that the
|
||||||
|
// given 'val' is an IpnsEntry and that that entry is valid.
|
||||||
|
int ipns_validate_ipns_record (char *k, char *val)
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
struct ipns_entry *entry = ipfs_namesys_pb_new_ipns_entry();
|
||||||
|
struct timespec ts, now;
|
||||||
|
|
||||||
|
if (!entry) {
|
||||||
|
return ErrAllocFailed;
|
||||||
|
}
|
||||||
|
//err = proto.Unmarshal(val, entry);
|
||||||
|
if (err) {
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
if (ipfs_namesys_pb_get_validity_type (entry) == IpnsEntry_EOL) {
|
||||||
|
err = ipfs_util_time_parse_RFC3339 (&ts, ipfs_namesys_pb_get_validity (entry));
|
||||||
|
if (err) {
|
||||||
|
//log.Debug("failed parsing time for ipns record EOL")
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
timespec_get (&now, TIME_UTC);
|
||||||
|
if (now.tv_nsec > ts.tv_nsec || (now.tv_nsec == ts.tv_nsec && now.tv_nsec > ts.tv_nsec)) {
|
||||||
|
return ErrExpiredRecord;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return ErrUnrecognizedValidity;
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,15 +13,15 @@ char* ipfs_routing_cache_get (char *key, struct ipns_entry *ientry)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
struct routingResolver *cache;
|
struct routingResolver *cache;
|
||||||
struct stime now;
|
struct timespec now;
|
||||||
|
|
||||||
if (key && ientry) {
|
if (key && ientry) {
|
||||||
cache = ientry->cache;
|
cache = ientry->cache;
|
||||||
if (cache) {
|
if (cache) {
|
||||||
get_gmttime (&now);
|
timespec_get (&now);
|
||||||
for (i = 0 ; i < cache->next ; i++) {
|
for (i = 0 ; i < cache->next ; i++) {
|
||||||
if (((now.t < cache->data[i]->eol.t ||
|
if (((now.tv_sec < cache->data[i]->eol.tv_sec ||
|
||||||
(now.t == cache->data[i]->eol.t && now.ts.tv_nsec < cache->data[i]->eol.ts.tv_nsec))) &&
|
(now.tv_sec == cache->data[i]->eol.tv_sec && now.tv_nsec < cache->data[i]->eol.tv_nsec))) &&
|
||||||
strcmp(cache->data[i]->key, key) == 0) {
|
strcmp(cache->data[i]->key, key) == 0) {
|
||||||
return cache->data[i]->value;
|
return cache->data[i]->value;
|
||||||
}
|
}
|
||||||
|
@ -43,8 +43,8 @@ void ipfs_routing_cache_set (char *key, char *value, struct ipns_entry *ientry)
|
||||||
if (n) {
|
if (n) {
|
||||||
n->key = key;
|
n->key = key;
|
||||||
n->value = value;
|
n->value = value;
|
||||||
get_gmttime (&n->eol); // now
|
timespec_get (&n->eol); // now
|
||||||
n->eol.t += DefaultResolverCacheTTL; // sum TTL seconds to time seconds.
|
n->eol.tv_sec += DefaultResolverCacheTTL; // sum TTL seconds to time seconds.
|
||||||
cache->data[cache->next++] = n;
|
cache->data[cache->next++] = n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ int ipfs_namesys_routing_resolve_once (char **path, char *name, int depth, char
|
||||||
}
|
}
|
||||||
|
|
||||||
// check sig with pk
|
// check sig with pk
|
||||||
err = libp2p_crypto_verify (ipfs_ipns_entry_data_for_sig(pb->IpnsEntry), ipfs_ipns_entry_get_signature(pb->IpnsEntry), &ok);
|
err = libp2p_crypto_verify (ipns_entry_data_for_sig(pb->IpnsEntry), pb->IpnsEntry->signature, &ok);
|
||||||
if (err || !ok) {
|
if (err || !ok) {
|
||||||
char buf[500];
|
char buf[500];
|
||||||
snprintf(buf, sizeof(buf), Err[ErrInvalidSignatureFmt], pubkey);
|
snprintf(buf, sizeof(buf), Err[ErrInvalidSignatureFmt], pubkey);
|
||||||
|
@ -198,12 +198,12 @@ int ipfs_namesys_routing_resolve_once (char **path, char *name, int depth, char
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int ipfs_namesys_routing_check_EOL (struct stime *st, struct namesys_pb *pb)
|
int ipfs_namesys_routing_check_EOL (struct timespec *ts, struct namesys_pb *pb)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (ipfs_namesys_pb_get_validity_type (pb->IpnsEntry) == IpnsEntry_EOL) {
|
if (*(pb->IpnsEntry->validityType) == IpnsEntry_EOL) {
|
||||||
err = ipfs_util_time_parse_RFC3339 (st, ipfs_namesys_pb_get_validity (pb->IpnsEntry));
|
err = ipfs_util_time_parse_RFC3339 (ts, pb->IpnsEntry->validity);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
35
util/time.c
35
util/time.c
|
@ -1,47 +1,26 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#ifndef __USE_XOPEN
|
|
||||||
#define __USE_XOPEN
|
|
||||||
#endif // __USE_XOPEN
|
|
||||||
|
|
||||||
#ifndef __USE_ISOC11
|
|
||||||
#define __USE_ISOC11
|
|
||||||
#endif // __USE_ISOC11
|
|
||||||
|
|
||||||
#include <time.h>
|
|
||||||
#include "ipfs/util/time.h"
|
#include "ipfs/util/time.h"
|
||||||
|
|
||||||
int get_gmttime(struct stime *st) {
|
int ipfs_util_time_parse_RFC3339 (struct timespec *ts, char *s)
|
||||||
if (!st) {
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (!timespec_get(&st->ts, TIME_UTC) ||
|
|
||||||
!time(&st->t)) {
|
|
||||||
return 2;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int ipfs_util_time_parse_RFC3339 (struct stime *st, char *s)
|
|
||||||
{
|
{
|
||||||
char *r;
|
char *r;
|
||||||
struct tm tm;
|
struct tm tm;
|
||||||
|
|
||||||
if (!st || !s || strlen(s) != 35) {
|
if (!ts || !s || strlen(s) != 35) {
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
r = strptime (s, "%Y-%m-%dT%H:%M:%S", &tm);
|
r = strptime (s, "%Y-%m-%dT%H:%M:%S", &tm);
|
||||||
if (!r || *r != '.') {
|
if (!r || *r != '.') {
|
||||||
return 2;
|
return 2;
|
||||||
}
|
}
|
||||||
st->t = mktime(&tm);
|
ts->tv_sec = mktime(&tm);
|
||||||
st->ts.tv_nsec = atoll(++r);
|
ts->tv_nsec = atoll(++r);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *ipfs_util_time_format_RFC3339 (struct stime *st)
|
char *ipfs_util_time_format_RFC3339 (struct timespec *ts)
|
||||||
{
|
{
|
||||||
char buf[31], *ret;
|
char buf[31], *ret;
|
||||||
|
|
||||||
|
@ -50,8 +29,8 @@ char *ipfs_util_time_format_RFC3339 (struct stime *st)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S.%%09dZ00:00", gmtime(&st->t)) != sizeof(buf)-1 ||
|
if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S.%%09dZ00:00", gmtime(&(ts->tv_sec))) != sizeof(buf)-1 ||
|
||||||
snprintf(ret, 36, buf, st->ts.tv_nsec) != 35) {
|
snprintf(ret, 36, buf, ts->tv_nsec) != 35) {
|
||||||
free (ret);
|
free (ret);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue