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
|
||||
#define IPNS_NAMESYS_PB_H
|
||||
#include <stdint.h>
|
||||
|
||||
typedef int IpnsEntry_ValidityType;
|
||||
typedef int32_t IpnsEntry_ValidityType;
|
||||
|
||||
struct ipns_entry {
|
||||
// TODO
|
||||
struct routingResolver *cache;
|
||||
struct stime *eol;
|
||||
char *value;
|
||||
char *signature;
|
||||
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 {
|
||||
// TODO
|
||||
struct ipns_entry *IpnsEntry;
|
||||
|
@ -23,8 +28,9 @@
|
|||
};
|
||||
|
||||
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_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*);
|
||||
int ipfs_namesys_pb_get_value (char**, 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 {
|
||||
char *key;
|
||||
char *value;
|
||||
struct stime eol;
|
||||
struct timespec eol;
|
||||
};
|
||||
|
||||
struct routingResolver {
|
||||
|
@ -29,7 +29,8 @@
|
|||
// ipfs_namesys_routing_resolve_once implements resolver. Uses the IPFS
|
||||
// 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_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_getpublic_key (char*, struct MultiHash*);
|
||||
#endif // IPNS_NAMESYS_ROUTING_H
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
#ifndef IPFS_TIME_H
|
||||
#define IPFS_TIME_H
|
||||
#ifndef __USE_XOPEN
|
||||
#define __USE_XOPEN
|
||||
#endif // __USE_XOPEN
|
||||
|
||||
struct stime {
|
||||
time_t t;
|
||||
struct timespec ts;
|
||||
};
|
||||
#ifndef __USE_ISOC11
|
||||
#define __USE_ISOC11
|
||||
#endif // __USE_ISOC11
|
||||
|
||||
int get_gmttime(struct stime *st);
|
||||
int ipfs_util_time_parse_RFC3339 (struct stime *st, char *s);
|
||||
char *ipfs_util_time_format_RFC3339 (struct stime *st);
|
||||
#include <time.h>
|
||||
|
||||
int ipfs_util_time_parse_RFC3339 (struct timespec *ts, char *s);
|
||||
char *ipfs_util_time_format_RFC3339 (struct timespec *ts);
|
||||
#endif // IPFS_TIME_H
|
||||
|
|
22
namesys/pb.c
22
namesys/pb.c
|
@ -1,4 +1,5 @@
|
|||
#include <string.h>
|
||||
#include "ipfs/namesys/routing.h"
|
||||
#include "ipfs/namesys/pb.h"
|
||||
|
||||
int IpnsEntry_ValidityType_value (char *s)
|
||||
|
@ -17,3 +18,24 @@ int IpnsEntry_ValidityType_value (char *s)
|
|||
|
||||
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;
|
||||
struct routingResolver *cache;
|
||||
struct stime now;
|
||||
struct timespec now;
|
||||
|
||||
if (key && ientry) {
|
||||
cache = ientry->cache;
|
||||
if (cache) {
|
||||
get_gmttime (&now);
|
||||
timespec_get (&now);
|
||||
for (i = 0 ; i < cache->next ; i++) {
|
||||
if (((now.t < cache->data[i]->eol.t ||
|
||||
(now.t == cache->data[i]->eol.t && now.ts.tv_nsec < cache->data[i]->eol.ts.tv_nsec))) &&
|
||||
if (((now.tv_sec < cache->data[i]->eol.tv_sec ||
|
||||
(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) {
|
||||
return cache->data[i]->value;
|
||||
}
|
||||
|
@ -43,8 +43,8 @@ void ipfs_routing_cache_set (char *key, char *value, struct ipns_entry *ientry)
|
|||
if (n) {
|
||||
n->key = key;
|
||||
n->value = value;
|
||||
get_gmttime (&n->eol); // now
|
||||
n->eol.t += DefaultResolverCacheTTL; // sum TTL seconds to time seconds.
|
||||
timespec_get (&n->eol); // now
|
||||
n->eol.tv_sec += DefaultResolverCacheTTL; // sum TTL seconds to time seconds.
|
||||
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
|
||||
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) {
|
||||
char buf[500];
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
if (ipfs_namesys_pb_get_validity_type (pb->IpnsEntry) == IpnsEntry_EOL) {
|
||||
err = ipfs_util_time_parse_RFC3339 (st, ipfs_namesys_pb_get_validity (pb->IpnsEntry));
|
||||
if (*(pb->IpnsEntry->validityType) == IpnsEntry_EOL) {
|
||||
err = ipfs_util_time_parse_RFC3339 (ts, pb->IpnsEntry->validity);
|
||||
if (!err) {
|
||||
return 1;
|
||||
}
|
||||
|
|
35
util/time.c
35
util/time.c
|
@ -1,47 +1,26 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.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"
|
||||
|
||||
int get_gmttime(struct stime *st) {
|
||||
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)
|
||||
int ipfs_util_time_parse_RFC3339 (struct timespec *ts, char *s)
|
||||
{
|
||||
char *r;
|
||||
struct tm tm;
|
||||
|
||||
if (!st || !s || strlen(s) != 35) {
|
||||
if (!ts || !s || strlen(s) != 35) {
|
||||
return 1;
|
||||
}
|
||||
r = strptime (s, "%Y-%m-%dT%H:%M:%S", &tm);
|
||||
if (!r || *r != '.') {
|
||||
return 2;
|
||||
}
|
||||
st->t = mktime(&tm);
|
||||
st->ts.tv_nsec = atoll(++r);
|
||||
ts->tv_sec = mktime(&tm);
|
||||
ts->tv_nsec = atoll(++r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
char *ipfs_util_time_format_RFC3339 (struct stime *st)
|
||||
char *ipfs_util_time_format_RFC3339 (struct timespec *ts)
|
||||
{
|
||||
char buf[31], *ret;
|
||||
|
||||
|
@ -50,8 +29,8 @@ char *ipfs_util_time_format_RFC3339 (struct stime *st)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S.%%09dZ00:00", gmtime(&st->t)) != sizeof(buf)-1 ||
|
||||
snprintf(ret, 36, buf, st->ts.tv_nsec) != 35) {
|
||||
if (strftime(buf, sizeof(buf), "%Y-%m-%dT%H:%M:%S.%%09dZ00:00", gmtime(&(ts->tv_sec))) != sizeof(buf)-1 ||
|
||||
snprintf(ret, 36, buf, ts->tv_nsec) != 35) {
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue