2 protocol_node.c -- handle the meta-protocol, nodes
3 Copyright (C) 1999-2002 Ivo Timmermans <ivo@o2w.nl>,
4 2000-2002 Guus Sliepen <guus@sliepen.eu.org>
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.
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.
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.
20 $Id: protocol_node.c,v 1.1.4.4 2002/09/03 22:49:55 guus Exp $
41 #include "connection.h"
46 int send_add_node(connection_t *c, node_t *n)
51 if(!n->status.reachable)
54 sockaddr2str(&n->address, &address, &port);
55 x = send_request(c, "%d %s %s %s %lx %d", ADD_NODE,
56 n->name, address, port,
57 n->options, n->distance + 1); // Alternatively, use n->distance + c->estimated_weight
64 int add_node_h(connection_t *c)
68 char name[MAX_STRING_SIZE];
69 char address[MAX_STRING_SIZE];
70 char port[MAX_STRING_SIZE];
75 if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" %lx %d",
76 name, address, port, &options, &distance) != 5)
78 syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_NODE", c->name, c->hostname);
82 /* Check if names are valid */
86 syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_NODE", c->name, c->hostname, _("invalid name"));
90 /* This node is indirect if it's nexthop is as well */
92 if(c->node->options & OPTION_INDIRECT)
93 options |= OPTION_INDIRECT;
97 n = lookup_node(name);
101 // It's a new node. Add it and tell the others.
103 n->name = xstrdup(name);
104 n->address = str2sockaddr(address, port);
105 n->hostname = sockaddr2hostname(&n->address);
106 n->options = options;
107 n->distance = distance;
108 n->via = n->nexthop = c->node;
109 n->status.reachable = 1;
114 // If this ADD_NODE is closer or more direct, use it instead of the old one.
115 if(!n->status.reachable || ((n->options & OPTION_INDIRECT) && !(options & OPTION_INDIRECT)) || n->distance > distance)
117 avl_node_t *node = avl_unlink(node_udp_tree, n);
118 n->address = str2sockaddr(address, port);
119 avl_insert_node(node_udp_tree, node);
122 n->hostname = sockaddr2hostname(&n->address);
123 n->options = options;
124 n->distance = distance;
125 n->via = n->nexthop = c->node;
126 n->status.reachable = 1;
127 n->status.validkey = 0;
128 n->status.waitingforkey = 0;
131 // Otherwise, just ignore it.
135 /* Tell the rest about the new node */
137 for(node = connection_tree->head; node; node = node->next)
139 other = (connection_t *)node->data;
140 if(other->status.active && other != c)
141 send_add_node(other, n);
148 int send_del_node(connection_t *c, node_t *n)
151 return send_request(c, "%d %s", DEL_NODE, n->name);
154 int del_node_h(connection_t *c)
156 char name[MAX_STRING_SIZE];
161 if(sscanf(c->buffer, "%*d "MAX_STRING, name) != 1)
163 syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_NODE",
164 c->name, c->hostname);
168 /* Check if names are valid */
172 syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_NODE", c->name, c->hostname, _("invalid name"));
178 n = lookup_node(name);
182 if(debug_lvl >= DEBUG_PROTOCOL)
183 syslog(LOG_WARNING, _("Got %s from %s (%s) which does not appear in the node tree"), "DEL_NODE", c->name, c->hostname);
187 /* If we got a DEL_NODE but we know of a different route to it, tell the one who send the DEL_NODE */
189 if(n->nexthop != c->node)
191 return send_add_node(c, n);
194 /* Otherwise, tell the rest about the deleted node */
196 for(node = connection_tree->head; node; node = node->next)
198 other = (connection_t *)node->data;
199 if(other->status.active && other != c)
200 send_del_node(other, n);
203 /* "Delete" the node */
205 n->status.reachable = 0;
206 n->status.validkey = 0;