123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499 |
- /* This file is part of Netsukuku
- * (c) Copyright 2005 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
- *
- * This source code is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as published
- * by the Free Software Foundation; either version 2 of the License,
- * or (at your option) any later version.
- *
- * This source code is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- * Please refer to the GNU Public License for more details.
- *
- * You should have received a copy of the GNU Public License along with
- * this source code; if not, write to:
- * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- #ifndef ANDNA_CACHE_H
- #define ANDNA_CACHE_H
-
- #include "inet.h"
- #include "crypto.h"
- #include "endianness.h"
- #include "llist.c"
- #include "snsd_cache.h"
-
- /*
- * ANDNA definitions
- */
-
- #define ANDNA_MAX_BACKUP_GNODES 2
- #define ANDNA_MAX_QUEUE 5
- #define ANDNA_MAX_HNAME_LEN 512 /* (null terminator included) */
- #define ANDNA_MAX_HOSTNAMES 256 /* Max number of hnames per node */
- #define ANDNA_MAX_RHC_HNAMES 512 /* Max number of hnames kept in
- the resolved_hnames cache* */
- #define ANDNA_EXPIRATION_TIME 259200 /* 3 days (in seconds)*/
- #define ANDNA_MIN_UPDATE_TIME 3600 /* The minum amount of time to
- be waited before sending an
- update of the hname. */
-
- #define ANDNA_PRIVKEY_BITS 1024
- #define ANDNA_SKEY_MAX_LEN 900
- #define ANDNA_PKEY_LEN 140
- #define ANDNA_HASH_SZ (MAX_IP_SZ)
- #define ANDNA_SIGNATURE_LEN 128
-
- /* Returns the number of nodes to be used in a backup_gnode */
- #define ANDNA_BACKUP_NODES(seeds) ({(seeds) > 8 ? \
- ((seeds)*32)/MAXGROUPNODE : (seeds);})
-
- #ifdef DEBUG
- #undef ANDNA_EXPIRATION_TIME
- #define ANDNA_EXPIRATION_TIME 100
- #undef ANDNA_MIN_UPDATE_TIME
- #define ANDNA_MIN_UPDATE_TIME 2
- #endif
-
- /*
- * * * Cache stuff * * *
- */
-
- /* * andna_cache flags * */
- #define ANDNA_BACKUP 1 /* We are a backup_node */
- #define ANDNA_COUNTER (1<<1) /* We are a counter_node */
- #define ANDNA_ROUNDED (1<<2) /* We are a rounded_hash_node */
- #define ANDNA_FULL (1<<3) /* Queue full */
- #define ANDNA_UPDATING (1<<4) /* The hname is being updated
- right now */
-
- /*
- * andna_cache_queue
- *
- * The queue of the andna_cache. (see below).
- */
- struct andna_cache_queue
- {
- LLIST_HDR (struct andna_cache_queue);
-
- time_t timestamp;
- u_short hname_updates; /* numbers of hname's updates */
- char pubkey[ANDNA_PKEY_LEN];
-
- u_short snsd_counter; /* # of `snsd' nodes */
- snsd_service *service;
- };
- typedef struct andna_cache_queue andna_cache_queue;
-
- /*
- * andna_cache
- *
- * It keeps the entries of the hostnames registered by other nodes.
- */
- struct andna_cache
- {
- LLIST_HDR (struct andna_cache);
-
- u_int hash[MAX_IP_INT]; /* hostname's hash */
- char flags;
-
- u_short queue_counter;
- andna_cache_queue *acq; /* The queue of the registration.
- The first is the active one */
- };
- typedef struct andna_cache andna_cache;
-
- /* part of the counter cache, see below */
- struct counter_c_hashes
- {
- LLIST_HDR (struct counter_c_hashes);
-
- time_t timestamp;
- u_short hname_updates;
- int hash[MAX_IP_INT];
- };
- typedef struct counter_c_hashes counter_c_hashes;
- INT_INFO counter_c_hashes_body_iinfo = { 2,
- { INT_TYPE_32BIT, INT_TYPE_16BIT },
- { 0, sizeof(time_t) },
- { 1, 1 }
- };
-
- /*
- * counter_c
- * Counter node's cache.
- *
- * All the infos regarding a particular register_node are stored here. For
- * example, we need to know how many hostnames he already registered.
- */
- struct counter_c
- {
- LLIST_HDR (struct counter_c);
-
- char pubkey[ANDNA_PKEY_LEN];
- char flags;
-
- u_short hashes; /* The number of hashes in cch */
- counter_c_hashes *cch; /* The hashes of the hnames */
- };
- typedef struct counter_c counter_c;
- INT_INFO counter_c_body_iinfo = { 1,
- { INT_TYPE_16BIT },
- { ANDNA_PKEY_LEN+sizeof(char) },
- { 1 }
- };
-
- /*
- * lcl_cache_keyring
- *
- * The lcl keyring is used to store the RSA keys used to complete some of the
- * ANDNA requests, (f.e. registering or updating a hname).
- */
- typedef struct
- {
- u_int skey_len;
- u_int pkey_len;
-
- u_char *privkey; /* secret key packed */
- u_char *pubkey; /* pubkey packed */
-
- RSA *priv_rsa; /* key pair unpacked */
- } lcl_cache_keyring;
-
-
- /*
- * lcl_cache
- *
- * The Local Andna Cache keeps all the hostnames which have been register by
- * localhost (ourself).
- */
- struct lcl_cache
- {
- LLIST_HDR (struct lcl_cache);
-
- char *hostname; /* The registered hostname */
- u_int hash; /* 32bit hash of the md5 hash
- of the hname */
- u_short hname_updates; /* How many updates we've done
- for this hostname */
- time_t timestamp; /* the last time when the hname
- was updated. If it is 0, the
- hname has still to be
- registered */
-
- u_short snsd_counter; /* # of `snsds' */
- snsd_service *service;
-
- char flags;
- };
- typedef struct lcl_cache lcl_cache;
-
-
- /*
- * resolved_hnames_cache
- *
- * This cache keeps info on the already resolved hostnames, so we won't have
- * to resolve them soon again.
- * In order to optimize the search we order the linked list by the time
- * of hname resolution. The last hname which has been searched/resolved is
- * always moved at the head of the llist, in this way, at the end of the llist
- * there is the hname which has been searched for the first time but has been
- * ignored until now.
- * When the cache is full, the hname which is at the end of the llist is
- * removed to empty new space.
- * The hname which have the `timestamp' expired are removed too.
- */
- struct resolved_hnames_cache
- {
- LLIST_HDR (struct resolved_hnames_cache);
-
- u_int hash; /* 32bit hash of the md5 hash of the
- hname */
- char flags;
-
- time_t timestamp; /* the last time when the hname
- was updated. With this we know that
- at timestamp+ANDNA_EXPIRATION_TIME
- this cache will expire. */
-
- u_short snsd_counter;
- snsd_service *service;
- };
- typedef struct resolved_hnames_cache rh_cache;
-
-
- /*
- * * * * Global vars * * *
- */
- andna_cache *andna_c;
- int andna_c_counter;
-
- counter_c *andna_counter_c;
- int cc_counter;
-
- lcl_cache_keyring lcl_keyring;
- lcl_cache *andna_lcl;
- int lcl_counter;
-
- rh_cache *andna_rhc;
- int rhc_counter;
-
-
- /*
- *
- * * * * Package stuff * * *
- *
- */
-
-
- /*
- * * * * lcl cache package * * *
- */
-
- struct lcl_keyring_pkt_hdr
- {
- u_int skey_len;
- u_int pkey_len;
- }_PACKED_;
- /*
- * the rest of the pkt is:
- *
- * char privkey[hdr.skey_len];
- * char pubkey[hdr.pkey_len];
- */
- INT_INFO lcl_keyring_pkt_hdr_iinfo = { 2,
- { INT_TYPE_32BIT, INT_TYPE_32BIT },
- { 0, sizeof(u_int) },
- { 1, 1 }
- };
- #define LCL_KEYRING_HDR_PACK_SZ(khdr) (sizeof(struct lcl_keyring_pkt_hdr) + \
- (khdr)->skey_len + (khdr)->pkey_len)
-
- /*
- * The local cache pkt is used to pack the entire local cache to save it in a
- * file or to send it to a node.
- */
- struct lcl_cache_pkt_hdr
- {
- u_short tot_caches; /* How many lcl structs there
- are in the pkt's body */
- }_PACKED_;
- INT_INFO lcl_cache_pkt_hdr_iinfo = { 1, { INT_TYPE_16BIT }, { 0 }, { 1 } };
- #define LCL_CACHE_HDR_PACK_SZ (sizeof(struct lcl_cache_pkt_hdr))
-
- /*
- * The body is:
- *
- * struct lcl_cache_pkt_body {
- * u_short hname_updates;
- * time_t timestamp;
- * char hostname[strlen(hostname)+1]; * null terminated *
- * } body[ hdr.tot_caches ];
- *
- */
- #define LCL_CACHE_BODY_PACK_SZ(hname_len) ((hname_len) + sizeof(u_short) \
- + sizeof(time_t))
- INT_INFO lcl_cache_pkt_body_iinfo = { 2, { INT_TYPE_16BIT, INT_TYPE_32BIT },
- { 0, sizeof(u_short) },
- { 1, 1 }
- };
-
- /*
- * * * * andna cache package * * *
- */
-
- /*
- * the body of the acq_pkt is:
- * struct acq_pkt_body {
- * time_t timestamp;
- * u_short hname_updates;
- * char pubkey[ANDNA_PKEY_LEN];
- *
- * u_short snsd_counter;
- * char snsd_service_pack[SNSD_SERVICE_PACK_SZ];
- * };
- */
- INT_INFO acq_body_iinfo = { 3,
- { INT_TYPE_32BIT, INT_TYPE_16BIT, INT_TYPE_16BIT },
- { 0, sizeof(time_t),
- sizeof(time_t) + sizeof(u_short) + ANDNA_PKEY_LEN },
- { 1, 1, 1 }
- };
- #define ACQ_BODY_PACK_SZ (sizeof(time_t) + sizeof(u_short)*2 + \
- ANDNA_PKEY_LEN)
- #define ACQ_PACK_SZ(snsd_pack_sz) (ACQ_BODY_PACK_SZ + (snsd_pack_sz))
-
- struct andna_cache_pkt_hdr
- {
- u_short tot_caches;
- }_PACKED_;
- INT_INFO andna_cache_pkt_hdr_iinfo = { 1, { INT_TYPE_16BIT }, { 0 }, { 1 } };
- /*
- * The body is:
- * struct andna_cache_pack {
- * u_int hash[MAX_IP_INT];
- * char flags;
- * u_short queue_counter;
- * char acq_pack[ACQ_PACK_SZ*queue_counter];
- * } acache_pack[hdr.tot_caches];
- */
- INT_INFO andna_cache_body_iinfo = { 1,
- { INT_TYPE_16BIT },
- { MAX_IP_SZ+sizeof(char) },
- { 1 }
- };
- #define ACACHE_BODY_PACK_SZ (ANDNA_HASH_SZ + sizeof(char) + \
- sizeof(u_short))
- #define ACACHE_PACK_SZ(acq_pack_sz) ((acq_pack_sz) + ACACHE_BODY_PACK_SZ)
-
- /*
- * If the acache pack will be sent on a network packet, the `acq->timestamp'
- * will be the difference of the current time with the same `acq->timestamp',
- * in this way the node which receives the packet will add its current time to
- * `acq->timestamp'. This is necessary because the sending and receiving node
- * don't have the clock synced. Note that the rtt isn't considered because it
- * is generally very small and the ANDNA times don't need an accurate
- * precision, f.e. the expiration time is three days long.
- * If the pack is saved on a file, then `acq->timestamp' remains the same.
- * Problem: if the clock is changed, acq->timestamp will refer to the old
- * clock.
- */
- #define ACACHE_PACK_FILE 1
- #define ACACHE_PACK_PKT 2
-
-
- /*
- * The counter cache pkt is similar to the andna_cache_pkt, it is completely
- * arranged in the same way.
- */
- struct counter_c_pkt_hdr
- {
- u_short tot_caches;
- }_PACKED_;
- INT_INFO counter_c_pkt_hdr_iinfo = { 1, { INT_TYPE_16BIT }, { 0 }, { 1 } };
- #define COUNTER_CACHE_HASHES_PACK_SZ (sizeof(time_t) + sizeof(u_short) + \
- ANDNA_HASH_SZ)
- #define COUNTER_CACHE_BODY_PACK_SZ (ANDNA_PKEY_LEN + sizeof(char) + \
- sizeof(u_short))
- #define COUNTER_CACHE_PACK_SZ(hashes) ((COUNTER_CACHE_HASHES_PACK_SZ*(hashes))\
- + COUNTER_CACHE_BODY_PACK_SZ)
-
- /*
- * * * * Resolved hostnames cache pkt. * * *
- */
-
- struct rh_cache_pkt_hdr
- {
- u_short tot_caches; /* How many lcl structs there
- are in the pkt's hdr */
- }_PACKED_;
- INT_INFO rh_cache_pkt_hdr_iinfo = { 1, { INT_TYPE_16BIT }, { 0 }, { 1 } };
- /*
- * The body is:
- * struct rh_cache_pkt_body {
- * u_int hash;
- * char flags;
- * time_t timestamp;
- *
- * u_short snsd_counter;
- * char snsd_service_pack[SNSD_SERVICE_PACK_SZ];
- * } body[ hdr.tot_caches ];
- */
- #define RH_CACHE_BODY_PACK_SZ(snsd_pack_sz) (sizeof(u_int)+sizeof(char)+ \
- sizeof(time_t)+sizeof(u_short)+\
- (snsd_pack_sz))
- INT_INFO rh_cache_pkt_body_iinfo = { 3,
- { INT_TYPE_32BIT, INT_TYPE_32BIT, INT_TYPE_16BIT },
- { 0, sizeof(u_int)+sizeof(char),
- sizeof(u_int)+sizeof(char)+sizeof(time_t) },
- { 1, 1, 1 }
- };
-
-
- /*
- * * * Functions' declaration * * *
- */
-
- void andna_caches_init(int family);
-
- void lcl_new_keyring(lcl_cache_keyring *keyring);
- void lcl_destroy_keyring(lcl_cache_keyring *keyring);
- lcl_cache *lcl_cache_new(char *hname);
- void lcl_cache_free(lcl_cache *alcl);
- void lcl_cache_destroy(lcl_cache *head, int *counter);
- lcl_cache *lcl_cache_find_hname(lcl_cache *head, char *hname);
- lcl_cache *lcl_cache_find_hash(lcl_cache *alcl, u_int hash);
- lcl_cache *lcl_get_registered_hnames(lcl_cache *alcl);
-
- andna_cache_queue *ac_queue_findpubk(andna_cache *ac, char *pubk);
- andna_cache_queue *ac_queue_add(andna_cache *ac, char *pubkey);
- void ac_queue_del(andna_cache *ac, andna_cache_queue *acq);
- void ac_queue_del_expired(andna_cache *ac);
- void ac_queue_destroy(andna_cache *ac);
- andna_cache *andna_cache_findhash(int hash[MAX_IP_INT]);
- andna_cache *andna_cache_gethash(int hash[MAX_IP_INT]);
- andna_cache *andna_cache_addhash(int hash[MAX_IP_INT]);
- int andna_cache_del_ifexpired(andna_cache *ac);
- void andna_cache_del_expired(void);
- void andna_cache_destroy(void);
-
- counter_c_hashes *cc_hashes_add(counter_c *cc, int hash[MAX_IP_INT]);
- void cc_hashes_del(counter_c *cc, counter_c_hashes *cch);
- int counter_c_del_ifexpired(counter_c *cc);
- void cc_hashes_del_expired(counter_c *cc);
- void cc_hashes_destroy(counter_c *cc);
- counter_c_hashes *cc_findhash(counter_c *cc, int hash[MAX_IP_INT]);
- counter_c *counter_c_findpubk(char *pubk);
- counter_c *counter_c_add(inet_prefix *rip, char *pubkey);
- void counter_c_del_expired(void);
- void counter_c_destroy(void);
-
- rh_cache *rh_cache_new(char *hname, time_t timestamp);
- rh_cache *rh_cache_add_hash(u_int hash, time_t timestamp);
- rh_cache *rh_cache_add(char *hname, time_t timestamp);
- rh_cache *rh_cache_find_hash(u_int hash);
- rh_cache *rh_cache_find_hname(char *hname);
- void rh_cache_del(rh_cache *rhc);
- void rh_cache_del_expired(void);
- void rh_cache_flush(void);
-
- char *pack_lcl_keyring(lcl_cache_keyring *keyring, size_t *pack_sz);
- int unpack_lcl_keyring(lcl_cache_keyring *keyring, char *pack, size_t pack_sz);
-
- char *pack_lcl_cache(lcl_cache *local_cache, size_t *pack_sz);
- lcl_cache *unpack_lcl_cache(char *pack, size_t pack_sz, int *counter);
-
- char *pack_andna_cache(andna_cache *acache, size_t *pack_sz, int pack_type);
- andna_cache *unpack_andna_cache(char *pack, size_t pack_sz, int *counter,
- int pack_type);
-
- char *pack_counter_cache(counter_c *countercache, size_t *pack_sz);
- counter_c *unpack_counter_cache(char *pack, size_t pack_sz, int *counter);
-
- char *pack_rh_cache(rh_cache *rhcache, size_t *pack_sz);
- rh_cache *unpack_rh_cache(char *pack, size_t pack_sz, int *counter);
-
- int save_lcl_keyring(lcl_cache_keyring *keyring, char *file);
- int load_lcl_keyring(lcl_cache_keyring *keyring, char *file);
-
- int save_lcl_cache(lcl_cache *lcl, char *file);
- lcl_cache *load_lcl_cache(char *file, int *counter);
-
- int save_andna_cache(andna_cache *acache, char *file);
- andna_cache *load_andna_cache(char *file, int *counter);
-
- int save_counter_c(counter_c *countercache, char *file);
- counter_c *load_counter_c(char *file, int *counter);
-
- int save_rh_cache(rh_cache *rh, char *file);
- rh_cache *load_rh_cache(char *file, int *counter);
-
- int load_hostnames(char *file, lcl_cache **old_alcl_head, int *old_alcl_counter);
- int load_snsd(char *file, lcl_cache *alcl_head);
-
- int add_resolv_conf(char *hname, char *file);
- int del_resolv_conf(char *hname, char *file);
-
- #endif /*ANDNA_CACHE_H*/
|