2 protocol_edge.c -- handle the meta-protocol, edges
3 Copyright (C) 1999-2002 Ivo Timmermans <itimmermans@bigfoot.com>,
4 2000-2002 Guus Sliepen <guus@sliepen.warande.net>
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_edge.c,v 1.1.4.2 2002/02/18 16:25:18 guus Exp $
41 #include "connection.h"
48 int send_add_edge(connection_t *c, edge_t *e)
51 char *from_tcpaddress, *from_tcpport, *from_udpaddress, *from_udpport;
52 char *to_tcpaddress, *to_tcpport, *to_udpaddress, *to_udpport;
54 sockaddr2str(&e->from.tcpaddress, &from_tcpaddress, &from_tcpport);
55 sockaddr2str(&e->from.udpaddress, &from_udpaddress, &from_udpport);
56 sockaddr2str(&e->to.tcpaddress, &to_tcpaddress, &to_tcpport);
57 sockaddr2str(&e->to.udpaddress, &to_udpaddress, &to_udpport);
58 x = send_request(c, "%d %s %s %s %s %s %s %s %s %lx %d", ADD_EDGE,
59 e->from.node->name, from_tcpaddress, from_tcpport, from_udpport,
60 e->to.node->name, to_tcpaddress, to_tcpport, to_udpport,
61 e->options, e->weight);
62 free(from_tcpaddress);
64 free(from_udpaddress);
74 int add_edge_h(connection_t *c)
79 char from_name[MAX_STRING_SIZE];
80 char to_name[MAX_STRING_SIZE];
81 char from_address[MAX_STRING_SIZE];
82 char from_tcpport[MAX_STRING_SIZE];
83 char from_udpport[MAX_STRING_SIZE];
84 char to_address[MAX_STRING_SIZE];
85 char to_tcpport[MAX_STRING_SIZE];
86 char to_udpport[MAX_STRING_SIZE];
87 sockaddr_t from_tcpaddress, from_udpaddress;
88 sockaddr_t to_tcpaddress, to_udpaddress;
93 if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" "MAX_STRING" %lx %d",
94 from_name, from_address, from_tcpport, from_udpport,
95 to_name, to_address, to_tcpport, to_udpport,
96 &options, &weight) != 10)
98 syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "ADD_EDGE", c->name, c->hostname);
102 /* Check if names are valid */
104 if(check_id(from_name))
106 syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_EDGE", c->name, c->hostname, _("invalid name"));
110 if(check_id(to_name))
112 syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "ADD_EDGE", c->name, c->hostname, _("invalid name"));
118 from = lookup_node(from_name);
123 from->name = xstrdup(from_name);
127 to = lookup_node(to_name);
132 to->name = xstrdup(to_name);
136 /* Convert addresses */
138 from_tcpaddress = str2sockaddr(from_address, from_tcpport);
139 from_udpaddress = str2sockaddr(from_address, from_udpport);
140 to_tcpaddress = str2sockaddr(to_address, to_tcpport);
141 to_udpaddress = str2sockaddr(to_address, to_udpport);
143 /* Check if edge already exists */
145 e = lookup_edge(from, to);
149 if(e->weight != weight || e->options != options
150 || ((e->from.node == from) && (sockaddrcmp(&e->from.tcpaddress, &from_tcpaddress) || sockaddrcmp(&e->from.udpaddress, &from_udpaddress) || sockaddrcmp(&e->to.tcpaddress, &to_tcpaddress) || sockaddrcmp(&e->to.udpaddress, &to_udpaddress)))
151 || ((e->from.node == to) && (sockaddrcmp(&e->from.tcpaddress, &to_tcpaddress) || sockaddrcmp(&e->from.udpaddress, &to_udpaddress) || sockaddrcmp(&e->to.tcpaddress, &from_tcpaddress) || sockaddrcmp(&e->to.udpaddress, &from_udpaddress)))
154 if(from == myself || to == myself)
156 if(debug_lvl >= DEBUG_PROTOCOL)
157 syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself which does not match existing entry"), "ADD_EDGE", c->name, c->hostname);
163 if(debug_lvl >= DEBUG_PROTOCOL)
164 syslog(LOG_WARNING, _("Got %s from %s (%s) which does not match existing entry"), "ADD_EDGE", c->name, c->hostname);
171 else if(from == myself || to == myself)
173 if(debug_lvl >= DEBUG_PROTOCOL)
174 syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself which does not exist"), "ADD_EDGE", c->name, c->hostname);
187 e->from.tcpaddress = from_tcpaddress;
188 e->from.udpaddress = from_udpaddress;
190 e->to.tcpaddress = to_tcpaddress;
191 e->to.udpaddress = to_udpaddress;
192 e->options = options;
196 /* Tell the rest about the new edge */
198 for(node = connection_tree->head; node; node = node->next)
200 other = (connection_t *)node->data;
201 if(other->status.active && other != c)
202 send_add_edge(other, e);
205 /* Run MST before or after we tell the rest? */
212 int send_del_edge(connection_t *c, edge_t *e)
215 return send_request(c, "%d %s %s", DEL_EDGE,
216 e->from.node->name, e->to.node->name);
219 int del_edge_h(connection_t *c)
222 char from_name[MAX_STRING_SIZE];
223 char to_name[MAX_STRING_SIZE];
228 if(sscanf(c->buffer, "%*d "MAX_STRING" "MAX_STRING"", from_name, to_name) != 2)
230 syslog(LOG_ERR, _("Got bad %s from %s (%s)"), "DEL_EDGE",
231 c->name, c->hostname);
235 /* Check if names are valid */
237 if(check_id(from_name))
239 syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_EDGE", c->name, c->hostname, _("invalid name"));
243 if(check_id(to_name))
245 syslog(LOG_ERR, _("Got bad %s from %s (%s): %s"), "DEL_EDGE", c->name, c->hostname, _("invalid name"));
251 from = lookup_node(from_name);
255 if(debug_lvl >= DEBUG_PROTOCOL)
256 syslog(LOG_ERR, _("Got %s from %s (%s) which does not appear in the edge tree"), "DEL_EDGE", c->name, c->hostname);
260 to = lookup_node(to_name);
264 if(debug_lvl >= DEBUG_PROTOCOL)
265 syslog(LOG_ERR, _("Got %s from %s (%s) which does not appear in the edge tree"), "DEL_EDGE", c->name, c->hostname);
269 /* Check if edge exists */
271 e = lookup_edge(from, to);
275 if(debug_lvl >= DEBUG_PROTOCOL)
276 syslog(LOG_WARNING, _("Got %s from %s (%s) which does not appear in the edge tree"), "DEL_EDGE", c->name, c->hostname);
280 if(e->from.node == myself || e->to.node == myself)
282 if(debug_lvl >= DEBUG_PROTOCOL)
283 syslog(LOG_WARNING, _("Got %s from %s (%s) for ourself"), "DEL_EDGE", c->name, c->hostname);
284 send_add_edge(c, e); /* Send back a correction */
288 /* Tell the rest about the deleted edge */
290 for(node = connection_tree->head; node; node = node->next)
292 other = (connection_t *)node->data;
293 if(other->status.active && other != c)
294 send_del_edge(other, e);
297 /* Delete the edge */
301 /* Run MST before or after we tell the rest? */