You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

snsd_cache.h 9.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /* This file is part of Netsukuku
  2. * (c) Copyright 2006 Andrea Lo Pumo aka AlpT <alpt@freaknet.org>
  3. *
  4. * This source code is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU General Public License as published
  6. * by the Free Software Foundation; either version 2 of the License,
  7. * or (at your option) any later version.
  8. *
  9. * This source code is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  12. * Please refer to the GNU Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Public License along with
  15. * this source code; if not, write to:
  16. * Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17. */
  18. #ifndef SNSD_H
  19. #define SNSD_H
  20. #include "inet.h"
  21. #include "crypto.h"
  22. #include "endianness.h"
  23. #include "llist.c"
  24. /*
  25. * SNSD definitions
  26. */
  27. #define SNSD_MAX_RECORDS 256 /* Number of maximum SNSD records
  28. which can be stored in an
  29. andna_cache */
  30. #define SNSD_MAX_QUEUE_RECORDS 1 /* There can be only one snsd
  31. record for the queued hnames */
  32. #define SNSD_MAX_REC_SERV 16 /* Maximum records per service */
  33. #define SNSD_ALL_SERVICE (-1) /* A service number equal to -1
  34. refers to all the available
  35. services */
  36. #define SNSD_DEFAULT_SERVICE 0
  37. #define SNSD_DEFAULT_PROTO 1 /* tcp */
  38. #define SNSD_DEFAULT_PRIO 16
  39. #define SNSD_DEFAULT_WEIGHT 1
  40. #define SNSD_WEIGHT(x) ((x) & 0x7f) /* The snsd weight has to
  41. be <= 127 */
  42. /* Fields used in the syntax for the `snsd_nodes' file:
  43. * hostname:snsd_hostname:service:priority:weight[:pub_key_file]
  44. */
  45. #define MAX_SNSD_LINE_SZ (ANDNA_MAX_HNAME_LEN*4)
  46. #define MAX_SNSD_FIELDS 6
  47. #define MIN_SNSD_FIELDS 5
  48. /* * snsd_node flags * */
  49. #define SNSD_NODE_HNAME 1 /* A hname is associated in the
  50. snsd record */
  51. #define SNSD_NODE_IP (1<<1) /* An IP is associated in the
  52. snsd record */
  53. #define SNSD_NODE_MAIN_IP (1<<2) /* This is the first IP registered
  54. to the hname, it can't be
  55. deleted */
  56. /*
  57. * snsd_node, snsd_service, snsd_prio
  58. *
  59. * They are three linked list. They are all orthogonal to each other.
  60. * The snsd_node llist is inside each snsd_prio struct which is inside each
  61. * snsd_service struct:
  62. * || service X <-> service Y <-> service Z <-> ... ||
  63. * | | |
  64. * V V V
  65. * snsd_prio_1-->node snsd_prio_1-->node ...-->...
  66. * | |
  67. * V V
  68. * snsd_prio_2-->node ...-->node
  69. * |
  70. * V
  71. * ...-->node
  72. *
  73. * Using this schema, we don't have to sort them, ever. The nodes are already
  74. * grouped by service and in each service by priority.
  75. *
  76. * These llist are directly embedded in the andna_cache, lcl_cache and
  77. * rh_cache.
  78. *
  79. * The andna_cache keeps all the SNSD nodes associated to the registered
  80. * hostname. The andna_cache doesn't need `snsd_node->pubkey'.
  81. *
  82. * The rh_cache stores only records which are of the SNSD_NODE_IP type.
  83. *
  84. * When the lcl_cache is saved, its snsd llist is discarded because it is
  85. * loaded each time from the /etc/netsukuku/snsd_nodes file.
  86. */
  87. struct snsd_node {
  88. LLIST_HDR(struct snsd_node);
  89. uintptr_t record[MAX_IP_INT]; /* It can be the IP or the md5
  90. hash of the hname of the
  91. SNSD node */
  92. RSA *pubkey; /* pubkey of the snsd_node */
  93. char flags; /* This will tell us what
  94. `record' is */
  95. u_char weight;
  96. };
  97. typedef struct snsd_node snsd_node;
  98. /* In the pack of a snsd_node we don't save the `pubkey' */
  99. #define SNSD_NODE_PACK_SZ (MAX_IP_SZ+sizeof(char)*2)
  100. struct snsd_prio {
  101. LLIST_HDR(struct snsd_prio);
  102. u_char prio; /* Priority of the SNSD node */
  103. snsd_node *node;
  104. };
  105. typedef struct snsd_prio snsd_prio;
  106. #define SNSD_PRIO_PACK_SZ (sizeof(char))
  107. struct snsd_service {
  108. LLIST_HDR(struct snsd_service);
  109. u_short service; /* Service number */
  110. u_char proto; /* TCP/UDP, see the `proto_str'
  111. static array below */
  112. snsd_prio *prio;
  113. };
  114. typedef struct snsd_service snsd_service;
  115. #define SNSD_SERVICE_PACK_SZ (sizeof(u_short)+sizeof(u_char))
  116. /*
  117. *
  118. * * * * snsd structs package * * *
  119. *
  120. */
  121. struct snsd_node_llist_hdr {
  122. u_short count; /* # of snsd_node structs packed
  123. in the body */
  124. } _PACKED_;
  125. INT_INFO snsd_node_llist_hdr_iinfo = { 1, {INT_TYPE_16BIT}, {0}, {1} };
  126. /*
  127. * the body of the pkt is:
  128. *
  129. * struct snsd_node_pack {
  130. * u_int record[MAX_IP_INT];
  131. * char flags;
  132. * u_char weight;
  133. * } pack[hdr.nodes];
  134. */
  135. #define SNSD_NODE_LLIST_PACK_SZ(head) (list_count((head))*SNSD_NODE_PACK_SZ \
  136. + sizeof(struct snsd_node_llist_hdr))
  137. struct snsd_prio_llist_hdr {
  138. u_short count; /* number of structs packed in
  139. the body */
  140. } _PACKED_;
  141. INT_INFO snsd_prio_llist_hdr_iinfo = { 1, {INT_TYPE_16BIT}, {0}, {1} };
  142. /*
  143. * the body is:
  144. *
  145. * snsd_prio_pack {
  146. * u_char prio;
  147. * char snsd_node_llist_pack[SNSD_NODE_LLIST_PACK_SZ];
  148. * } pack[hdr.count];
  149. */
  150. #define SNSD_PRIO_LLIST_PACK_SZ(head) \
  151. ({ \
  152. snsd_prio *_p=(head); \
  153. int _priosz=0; \
  154. \
  155. list_for(_p) { \
  156. _priosz+=SNSD_NODE_LLIST_PACK_SZ(_p->node); \
  157. _priosz+=SNSD_PRIO_PACK_SZ; \
  158. } \
  159. _priosz+=sizeof(struct snsd_prio_llist_hdr); \
  160. _priosz; \
  161. })
  162. struct snsd_service_llist_hdr {
  163. u_short count;
  164. } _PACKED_;
  165. INT_INFO snsd_service_llist_hdr_iinfo = { 1, {INT_TYPE_16BIT}, {0}, {1} };
  166. /*
  167. * the body is:
  168. * u_short service;
  169. * u_char proto;
  170. * char snsd_prio_llist_pack[SNSD_PRIO_LLIST_PACK_SZ];
  171. */
  172. #define SNSD_SERVICE_LLIST_PACK_SZ(head) \
  173. ({ \
  174. snsd_service *_s=(head); \
  175. int _srvsz=0; \
  176. if(_s) { \
  177. list_for(_s) { \
  178. _srvsz+=SNSD_PRIO_LLIST_PACK_SZ(_s->prio); \
  179. _srvsz+=SNSD_SERVICE_PACK_SZ; \
  180. } \
  181. _srvsz+=sizeof(struct snsd_service_llist_hdr); \
  182. } \
  183. _srvsz; \
  184. })
  185. #define SNSD_SERVICE_SINGLE_PACK_SZ(head) \
  186. ({ SNSD_SERVICE_PACK_SZ + \
  187. SNSD_PRIO_LLIST_PACK_SZ((head)->prio); \
  188. })
  189. #define SNSD_SERVICE_MAX_PACK_SZ \
  190. ( ( (SNSD_NODE_PACK_SZ + SNSD_PRIO_PACK_SZ) * \
  191. (SNSD_MAX_REC_SERV) ) + \
  192. SNSD_SERVICE_PACK_SZ + \
  193. sizeof(struct snsd_prio_llist_hdr) + \
  194. sizeof(struct snsd_service_llist_hdr) \
  195. )
  196. #define SNSD_SERVICE_MAX_LLIST_PACK_SZ \
  197. (( SNSD_NODE_PACK_SZ + SNSD_PRIO_PACK_SZ + SNSD_SERVICE_PACK_SZ + \
  198. sizeof(struct snsd_prio_llist_hdr))*SNSD_MAX_RECORDS + \
  199. sizeof(struct snsd_service_llist_hdr) \
  200. )
  201. /*
  202. * This array is used to associate a 8bit number to a protocol name.
  203. * The number is the position of the protocol name in this array.
  204. * For example: "tcp" is in the first position so its associated number is 1,
  205. * while the number for "udp" is 2.
  206. *
  207. * Since we limit the proto number to an 8bit number, there can be only 255
  208. * protocols in this array.
  209. */
  210. const static char proto_str[][5] = {
  211. {"tcp"},
  212. {"udp"},
  213. {0},
  214. };
  215. /*
  216. *
  217. * * * Functions' declaration * * *
  218. *
  219. */
  220. void snsd_cache_init(int family);
  221. u_char str_to_snsd_proto(char *proto_name);
  222. const char *snsd_proto_to_str(u_char proto);
  223. int str_to_snsd_service(char *str, int *service, u_char * proto);
  224. struct servent *snsd_service_to_str(int service, u_char proto,
  225. char **service_str, char **proto_str);
  226. snsd_service *snsd_find_service(snsd_service * sns, u_short service,
  227. u_char proto);
  228. snsd_service *snsd_add_service(snsd_service ** head, u_short service,
  229. u_char proto);
  230. snsd_prio *snsd_find_prio(snsd_prio * snp, u_char prio);
  231. snsd_prio *snsd_add_prio(snsd_prio ** head, u_char prio);
  232. snsd_node *snsd_find_node_by_record(snsd_node * snd,
  233. uintptr_t record[MAX_IP_INT]);
  234. snsd_node *snsd_add_node(snsd_node ** head, u_short * counter,
  235. u_short max_records, uintptr_t record[MAX_IP_INT]);
  236. snsd_node *snsd_add_mainip(snsd_service ** head, u_short * counter,
  237. u_short max_records, uintptr_t record[MAX_IP_INT]);
  238. void snsd_service_llist_del(snsd_service ** head);
  239. void snsd_record_del_selected(snsd_service ** head, u_short * snd_counter,
  240. snsd_service * selected);
  241. int snsd_pack_service(char *pack, size_t free_sz, snsd_service * service);
  242. snsd_service *snsd_unpack_service(char *pack, size_t pack_sz,
  243. size_t * unpacked_sz,
  244. u_short * nodes_counter);
  245. int snsd_pack_all_services(char *pack, size_t pack_sz,
  246. snsd_service * head);
  247. snsd_service *snsd_unpack_all_service(char *pack, size_t pack_sz,
  248. size_t * unpacked_sz,
  249. u_short * nodes_counter);
  250. snsd_node *snsd_choose_wrand(snsd_node * head);
  251. snsd_prio *snsd_highest_prio(snsd_prio * head);
  252. snsd_node *snsd_find_mainip(snsd_service * sns);
  253. void snsd_unset_all_flags(snsd_service * sns, u_char flag);
  254. snsd_service *snsd_service_llist_copy(snsd_service * sns, int service,
  255. u_char proto);
  256. void snsd_merge_node(snsd_node ** head, u_short * snsd_counter,
  257. snsd_node * new);
  258. void snsd_node_llist_merge(snsd_node ** dst, u_short * snsd_counter,
  259. snsd_node * src);
  260. void snsd_merge_prio(snsd_prio ** head, u_short * snsd_counter,
  261. snsd_prio * new);
  262. void snsd_prio_llist_merge(snsd_prio ** dst, u_short * snsd_counter,
  263. snsd_prio * src);
  264. void snsd_merge_service(snsd_service ** head, u_short * snsd_counter,
  265. snsd_service * new);
  266. void snsd_service_llist_merge(snsd_service ** dst, u_short * snsd_counter,
  267. snsd_service * src);
  268. int snsd_count_nodes(snsd_node * head);
  269. int snsd_count_prio_nodes(snsd_prio * head);
  270. int snsd_count_service_nodes(snsd_service * head);
  271. #endif /*SNSD_H */