Hm.
[oweals/tinc.git] / lib / node.c
1 /*
2     node.c -- node tree management
3     Copyright (C) 2001-2002 Guus Sliepen <guus@sliepen.warande.net>,
4                   2001-2002 Ivo Timmermans <itimmermans@bigfoot.com>
5
6     This program is free software; you can redistribute it and/or modify
7     it under the terms of the GNU General Public License as published by
8     the Free Software Foundation; either version 2 of the License, or
9     (at your option) any later version.
10
11     This program is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14     GNU General Public License for more details.
15
16     You should have received a copy of the GNU General Public License
17     along with this program; if not, write to the Free Software
18     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20     $Id: node.c,v 1.1 2002/04/28 12:46:25 zarq Exp $
21 */
22
23 #include "config.h"
24
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include <avl_tree.h>
29 #include "node.h"
30 #include "netutl.h"
31 #include "net.h"
32 #include <utils.h>
33 #include <xalloc.h>
34 #include <hooks.h>
35
36 #include "logging.h"
37
38 #include "system.h"
39
40 avl_tree_t *node_tree;          /* Known nodes, sorted by name */
41 avl_tree_t *node_udp_tree;      /* Known nodes, sorted by address and port */
42
43 node_t *myself;
44
45 int node_compare(node_t *a, node_t *b)
46 {
47   return strcmp(a->name, b->name);
48 }
49
50 int node_udp_compare(node_t *a, node_t *b)
51 {
52   int result;
53 cp
54   result = sockaddrcmp(&a->address, &b->address);
55
56   if(result)
57     return result;
58
59   return (a->name && b->name)?strcmp(a->name, b->name):0;
60 }
61
62 void init_nodes(void)
63 {
64 cp
65   node_tree = avl_alloc_tree((avl_compare_t)node_compare, NULL);
66   node_udp_tree = avl_alloc_tree((avl_compare_t)node_udp_compare, NULL);
67 cp
68 }
69
70 void exit_nodes(void)
71 {
72 cp
73   avl_delete_tree(node_tree);
74   avl_delete_tree(node_udp_tree);
75 cp
76 }
77
78 node_t *new_node(void)
79 {
80   node_t *n = (node_t *)xmalloc_and_zero(sizeof(*n));
81 cp
82   n->subnet_tree = new_subnet_tree();
83   n->edge_tree = new_edge_tree();
84   n->queue = list_alloc((list_action_t)free);
85 cp
86   return n;
87 }
88
89 void free_node(node_t *n)
90 {
91 cp
92   if(n->queue)
93     list_delete_list(n->queue);
94   if(n->name)
95     free(n->name);
96   if(n->hostname)
97     free(n->hostname);
98   if(n->key)
99     free(n->key);
100   if(n->subnet_tree)
101     free_subnet_tree(n->subnet_tree);
102   if(n->edge_tree)
103     free_edge_tree(n->edge_tree);
104   free(n);
105 cp
106 }
107
108 void node_add(node_t *n)
109 {
110 cp
111   avl_insert(node_tree, n);
112   avl_insert(node_udp_tree, n);
113
114   run_hooks("node-add", n);
115 cp
116 }
117
118 void node_del(node_t *n)
119 {
120   avl_node_t *node, *next;
121   edge_t *e;
122   subnet_t *s;
123 cp
124   for(node = n->subnet_tree->head; node; node = next)
125     {
126       next = node->next;
127       s = (subnet_t *)node->data;
128       subnet_del(n, s);
129     }
130
131   for(node = n->subnet_tree->head; node; node = next)
132     {
133       next = node->next;
134       e = (edge_t *)node->data;
135       edge_del(e);
136     }
137 cp
138   avl_delete(node_tree, n);
139   avl_delete(node_udp_tree, n);
140
141   run_hooks("node-del", n);
142 cp
143 }
144
145 node_t *lookup_node(char *name)
146 {
147   node_t n;
148 cp
149   n.name = name;
150   return avl_search(node_tree, &n);
151 }
152
153 node_t *lookup_node_udp(sockaddr_t *sa)
154 {
155   node_t n;
156 cp
157   n.address = *sa;
158   n.name = NULL;
159
160   return avl_search(node_udp_tree, &n);
161 }
162
163 void dump_nodes(void)
164 {
165   avl_node_t *node;
166   node_t *n;
167 cp
168   log(0, TLOG_DEBUG,
169       _("Nodes:"));
170
171   for(node = node_tree->head; node; node = node->next)
172     {
173       n = (node_t *)node->data;
174 #ifdef USE_OPENSSL
175       syslog(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s"),
176              n->name, n->hostname, n->cipher?n->cipher->nid:0, n->digest?n->digest->type:0, n->maclength, n->compression, n->options,
177              n->status, n->nexthop?n->nexthop->name:"-", n->via?n->via->name:"-");
178 #endif
179 #ifdef USE_GCRYPT
180       syslog(LOG_DEBUG, _(" %s at %s cipher %d digest %d maclength %d compression %d options %lx status %04x nexthop %s via %s"),
181              n->name, n->hostname, n->cipher?-1:0, n->digest?-1:0, n->maclength, n->compression, n->options,
182              n->status, n->nexthop?n->nexthop->name:"-", n->via?n->via->name:"-");
183 #endif
184     }
185     
186   syslog(LOG_DEBUG, _("End of nodes."));
187 cp
188 }