The Netsukuku Project  0.0.9
An Alternative routing method
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros
snsd_cache.h
Go to the documentation of this file.
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 
19 #ifndef SNSD_H
20 #define SNSD_H
21 
22 #include "inet.h"
23 #include "crypto.h"
24 #include "endianness.h"
25 #include "llist.c"
26 
27 /*
28  * SNSD definitions
29  */
30 
31 #define SNSD_MAX_RECORDS 256 /* Number of maximum SNSD records
32  which can be stored in an
33  andna_cache */
34 #define SNSD_MAX_QUEUE_RECORDS 1 /* There can be only one snsd
35  record for the queued hnames */
36 #define SNSD_MAX_REC_SERV 16 /* Maximum records per service */
37 
38 #define SNSD_ALL_SERVICE (-1) /* A service number equal to -1
39  refers to all the available
40  services */
41 #define SNSD_DEFAULT_SERVICE 0
42 #define SNSD_DEFAULT_PROTO 1 /* tcp */
43 #define SNSD_DEFAULT_PRIO 16
44 #define SNSD_DEFAULT_WEIGHT 1
45 
46 #define SNSD_WEIGHT(x) ((x) & 0x7f) /* The snsd weight has to
47  be <= 127 */
48 
49 /* Fields used in the syntax for the `snsd_nodes' file:
50  * hostname:snsd_hostname:service:priority:weight[:pub_key_file]
51  */
52 #define MAX_SNSD_LINE_SZ (ANDNA_MAX_HNAME_LEN*4)
53 #define MAX_SNSD_FIELDS 6
54 #define MIN_SNSD_FIELDS 5
55 
56 /* * snsd_node flags * */
57 #define SNSD_NODE_HNAME 1 /* A hname is associated in the
58  snsd record */
59 #define SNSD_NODE_IP (1<<1) /* An IP is associated in the
60  snsd record */
61 #define SNSD_NODE_MAIN_IP (1<<2) /* This is the first IP registered
62  to the hname, it can't be
63  deleted */
64 
65 
66 /*
67  * snsd_node, snsd_service, snsd_prio
68  *
69  * They are three linked list. They are all orthogonal to each other.
70  * The snsd_node llist is inside each snsd_prio struct which is inside each
71  * snsd_service struct:
72  * || service X <-> service Y <-> service Z <-> ... ||
73  * | | |
74  * V V V
75  * snsd_prio_1-->node snsd_prio_1-->node ...-->...
76  * | |
77  * V V
78  * snsd_prio_2-->node ...-->node
79  * |
80  * V
81  * ...-->node
82  *
83  * Using this schema, we don't have to sort them, ever. The nodes are already
84  * grouped by service and in each service by priority.
85  *
86  * These llist are directly embedded in the andna_cache, lcl_cache and
87  * rh_cache.
88  *
89  * The andna_cache keeps all the SNSD nodes associated to the registered
90  * hostname. The andna_cache doesn't need `snsd_node->pubkey'.
91  *
92  * The rh_cache stores only records which are of the SNSD_NODE_IP type.
93  *
94  * When the lcl_cache is saved, its snsd llist is discarded because it is
95  * loaded each time from the /etc/netsukuku/snsd_nodes file.
96  */
97 struct snsd_node
98 {
99  LLIST_HDR (struct snsd_node);
100 
101  u_int record[MAX_IP_INT]; /* It can be the IP or the md5
102  hash of the hname of the
103  SNSD node */
104  RSA *pubkey; /* pubkey of the snsd_node */
105  char flags; /* This will tell us what
106  `record' is */
107 
108  u_char weight;
109 };
110 typedef struct snsd_node snsd_node;
111 /* In the pack of a snsd_node we don't save the `pubkey' */
112 #define SNSD_NODE_PACK_SZ (MAX_IP_SZ+sizeof(char)*2)
113 
114 struct snsd_prio
115 {
117 
118  u_char prio; /* Priority of the SNSD node */
119 
121 };
122 typedef struct snsd_prio snsd_prio;
123 #define SNSD_PRIO_PACK_SZ (sizeof(char))
124 
126 {
128 
129  u_short service; /* Service number */
130  u_char proto; /* TCP/UDP, see the `proto_str'
131  static array below */
132 
134 };
135 typedef struct snsd_service snsd_service;
136 #define SNSD_SERVICE_PACK_SZ (sizeof(u_short)+sizeof(u_char))
137 
138 
139 /*
140  *
141  * * * * snsd structs package * * *
142  *
143  */
144 
146 {
147  u_short count; /* # of snsd_node structs packed
148  in the body */
149 }_PACKED_;
151 /*
152  * the body of the pkt is:
153  *
154  * struct snsd_node_pack {
155  * u_int record[MAX_IP_INT];
156  * char flags;
157  * u_char weight;
158  * } pack[hdr.nodes];
159  */
160 #define SNSD_NODE_LLIST_PACK_SZ(head) (list_count((head))*SNSD_NODE_PACK_SZ \
161  + sizeof(struct snsd_node_llist_hdr))
162 
164 {
165  u_short count; /* number of structs packed in
166  the body */
167 }_PACKED_;
169 /*
170  * the body is:
171  *
172  * snsd_prio_pack {
173  * u_char prio;
174  * char snsd_node_llist_pack[SNSD_NODE_LLIST_PACK_SZ];
175  * } pack[hdr.count];
176  */
177 #define SNSD_PRIO_LLIST_PACK_SZ(head) \
178 ({ \
179  snsd_prio *_p=(head); \
180  int _priosz=0; \
181  \
182  list_for(_p) { \
183  _priosz+=SNSD_NODE_LLIST_PACK_SZ(_p->node); \
184  _priosz+=SNSD_PRIO_PACK_SZ; \
185  } \
186  _priosz+=sizeof(struct snsd_prio_llist_hdr); \
187  _priosz; \
188 })
189 
190 
192 {
193  u_short count;
194 }_PACKED_;
196 /*
197  * the body is:
198  * u_short service;
199  * u_char proto;
200  * char snsd_prio_llist_pack[SNSD_PRIO_LLIST_PACK_SZ];
201  */
202 #define SNSD_SERVICE_LLIST_PACK_SZ(head) \
203 ({ \
204  snsd_service *_s=(head); \
205  int _srvsz=0; \
206  if(_s) { \
207  list_for(_s) { \
208  _srvsz+=SNSD_PRIO_LLIST_PACK_SZ(_s->prio); \
209  _srvsz+=SNSD_SERVICE_PACK_SZ; \
210  } \
211  _srvsz+=sizeof(struct snsd_service_llist_hdr); \
212  } \
213  _srvsz; \
214 })
215 
216 #define SNSD_SERVICE_SINGLE_PACK_SZ(head) \
217 ({ SNSD_SERVICE_PACK_SZ + \
218  SNSD_PRIO_LLIST_PACK_SZ((head)->prio); \
219 })
220 
221 #define SNSD_SERVICE_MAX_PACK_SZ \
222 ( ( (SNSD_NODE_PACK_SZ + SNSD_PRIO_PACK_SZ) * \
223  (SNSD_MAX_REC_SERV) ) + \
224  SNSD_SERVICE_PACK_SZ + \
225  sizeof(struct snsd_prio_llist_hdr) + \
226  sizeof(struct snsd_service_llist_hdr) \
227 )
228 
229 #define SNSD_SERVICE_MAX_LLIST_PACK_SZ \
230 (( SNSD_NODE_PACK_SZ + SNSD_PRIO_PACK_SZ + SNSD_SERVICE_PACK_SZ + \
231  sizeof(struct snsd_prio_llist_hdr))*SNSD_MAX_RECORDS + \
232  sizeof(struct snsd_service_llist_hdr) \
233 )
234 
235 
236 /*
237  * This array is used to associate a 8bit number to a protocol name.
238  * The number is the position of the protocol name in this array.
239  * For example: "tcp" is in the first position so its associated number is 1,
240  * while the number for "udp" is 2.
241  *
242  * Since we limit the proto number to an 8bit number, there can be only 255
243  * protocols in this array.
244  */
245 const static char proto_str[][5] =
246 {
247  { "tcp" },
248  { "udp" },
249  { 0 },
250 };
251 
252 
253 
254 /*
255  *
256  * * * Functions' declaration * * *
257  *
258  */
259 
260 void snsd_cache_init(int family);
261 u_char str_to_snsd_proto(char *proto_name);
262 const char *snsd_proto_to_str(u_char proto);
263 int str_to_snsd_service(char *str, int *service, u_char *proto);
264 struct servent *snsd_service_to_str(int service, u_char proto,
265  char **service_str, char **proto_str);
266 
267 snsd_service *snsd_find_service(snsd_service *sns, u_short service, u_char proto);
268 snsd_service *snsd_add_service(snsd_service **head, u_short service, u_char proto);
269 snsd_prio *snsd_find_prio(snsd_prio *snp, u_char prio);
270 snsd_prio *snsd_add_prio(snsd_prio **head, u_char prio);
272 snsd_node *snsd_add_node(snsd_node **head, u_short *counter,
273  u_short max_records, u_int record[MAX_IP_INT]);
274 snsd_node *snsd_add_mainip(snsd_service **head, u_short *counter,
275  u_short max_records, u_int record[MAX_IP_INT]);
277 void snsd_record_del_selected(snsd_service **head, u_short *snd_counter,
278  snsd_service *selected);
279 
280 int snsd_pack_service(char *pack, size_t free_sz, snsd_service *service);
281 snsd_service *snsd_unpack_service(char *pack, size_t pack_sz,
282  size_t *unpacked_sz, u_short *nodes_counter);
283 int snsd_pack_all_services(char *pack, size_t pack_sz, snsd_service *head);
284 snsd_service *snsd_unpack_all_service(char *pack, size_t pack_sz,
285  size_t *unpacked_sz, u_short *nodes_counter);
286 
290 void snsd_unset_all_flags(snsd_service *sns, u_char flag);
292  u_char proto);
293 
294 void snsd_merge_node(snsd_node **head, u_short *snsd_counter, snsd_node *new);
295 void snsd_node_llist_merge(snsd_node **dst, u_short *snsd_counter, snsd_node *src);
296 void snsd_merge_prio(snsd_prio **head, u_short *snsd_counter, snsd_prio *new);
297 void snsd_prio_llist_merge(snsd_prio **dst, u_short *snsd_counter, snsd_prio *src);
298 void snsd_merge_service(snsd_service **head, u_short *snsd_counter,
299  snsd_service *new);
300 void snsd_service_llist_merge(snsd_service **dst, u_short *snsd_counter,
301  snsd_service *src);
302 
303 int snsd_count_nodes(snsd_node *head);
306 #endif /*SNSD_H*/
snsd_service * snsd_unpack_all_service(char *pack, size_t pack_sz, size_t *unpacked_sz, u_short *nodes_counter)
Definition: snsd_cache.c:780
void snsd_merge_node(snsd_node **head, u_short *snsd_counter, snsd_node *new)
Definition: snsd_cache.c:1045
char flags
Definition: snsd_cache.h:105
snsd_node * snsd_choose_wrand(snsd_node *head)
Definition: snsd_cache.c:865
snsd_service * snsd_unpack_service(char *pack, size_t pack_sz, size_t *unpacked_sz, u_short *nodes_counter)
Definition: snsd_cache.c:706
const char * snsd_proto_to_str(u_char proto)
Definition: snsd_cache.c:62
int snsd_count_prio_nodes(snsd_prio *head)
Definition: snsd_cache.c:839
Definition: snsd_cache.h:114
void snsd_merge_service(snsd_service **head, u_short *snsd_counter, snsd_service *new)
Definition: snsd_cache.c:1081
struct snsd_node_llist_hdr _PACKED_
static const int_info snsd_prio_llist_hdr_iinfo
Definition: snsd_cache.h:168
Definition: snsd_cache.h:97
u_short service
Definition: snsd_cache.h:129
#define INT_TYPE_16BIT
Definition: endianness.h:36
static const int_info snsd_node_llist_hdr_iinfo
Definition: snsd_cache.h:150
Definition: snsd_cache.h:163
void snsd_prio_llist_merge(snsd_prio **dst, u_short *snsd_counter, snsd_prio *src)
Definition: snsd_cache.c:1075
struct servent * snsd_service_to_str(int service, u_char proto, char **service_str, char **proto_str)
Definition: snsd_cache.c:120
void snsd_cache_init(int family)
Definition: snsd_cache.c:35
Definition: snsd_cache.h:145
u_short count
Definition: snsd_cache.h:147
snsd_prio * prio
Definition: snsd_cache.h:133
void snsd_node_llist_merge(snsd_node **dst, u_short *snsd_counter, snsd_node *src)
Definition: snsd_cache.c:1057
u_char proto
Definition: snsd_cache.h:130
snsd_node * node
Definition: snsd_cache.h:120
u_short count
Definition: snsd_cache.h:193
snsd_service * snsd_service_llist_copy(snsd_service *sns, int service, u_char proto)
Definition: snsd_cache.c:1016
Definition: snsd_cache.h:125
snsd_node * snsd_add_node(snsd_node **head, u_short *counter, u_short max_records, u_int record[4])
Definition: snsd_cache.c:211
int str_to_snsd_service(char *str, int *service, u_char *proto)
Definition: snsd_cache.c:84
void snsd_service_llist_merge(snsd_service **dst, u_short *snsd_counter, snsd_service *src)
Definition: snsd_cache.c:1106
int snsd_pack_all_services(char *pack, size_t pack_sz, snsd_service *head)
Definition: snsd_cache.c:746
u_char weight
Definition: snsd_cache.h:108
snsd_node * snsd_find_mainip(snsd_service *sns)
Definition: snsd_cache.c:913
void snsd_service_llist_del(snsd_service **head)
Definition: snsd_cache.c:295
#define MAX_IP_INT
Definition: inet.h:24
void snsd_record_del_selected(snsd_service **head, u_short *snd_counter, snsd_service *selected)
Definition: snsd_cache.c:314
RSA * pubkey
Definition: snsd_cache.h:104
u_short count
Definition: snsd_cache.h:165
snsd_prio * snsd_highest_prio(snsd_prio *head)
Definition: snsd_cache.c:894
u_char str_to_snsd_proto(char *proto_name)
Definition: snsd_cache.c:48
snsd_prio * snsd_add_prio(snsd_prio **head, u_char prio)
Definition: snsd_cache.c:177
u_int record[4]
Definition: snsd_cache.h:101
Definition: snsd_cache.h:191
snsd_node * snsd_add_mainip(snsd_service **head, u_short *counter, u_short max_records, u_int record[4])
Definition: snsd_cache.c:252
snsd_node * snsd_find_node_by_record(snsd_node *snd, u_int record[4])
Definition: snsd_cache.c:192
static const int_info snsd_service_llist_hdr_iinfo
Definition: snsd_cache.h:195
#define INT_INFO
Definition: endianness.h:90
void snsd_merge_prio(snsd_prio **head, u_short *snsd_counter, snsd_prio *new)
Definition: snsd_cache.c:1063
void snsd_unset_all_flags(snsd_service *sns, u_char flag)
Definition: snsd_cache.c:936
static const char proto_str[][5]
Definition: snsd_cache.h:245
int snsd_pack_service(char *pack, size_t free_sz, snsd_service *service)
Definition: snsd_cache.c:670
#define LLIST_HDR(_struct)
Definition: llist.c:44
int snsd_count_nodes(snsd_node *head)
Definition: snsd_cache.c:834
int family
Definition: if.c:34
snsd_prio * snsd_find_prio(snsd_prio *snp, u_char prio)
Definition: snsd_cache.c:169
int snsd_count_service_nodes(snsd_service *head)
Definition: snsd_cache.c:848
u_char prio
Definition: snsd_cache.h:118
snsd_service * snsd_find_service(snsd_service *sns, u_short service, u_char proto)
Definition: snsd_cache.c:141
snsd_service * snsd_add_service(snsd_service **head, u_short service, u_char proto)
Definition: snsd_cache.c:152