rsrr.c revision 1.7 1 1.7 wiz /* $NetBSD: rsrr.c,v 1.7 2003/03/05 21:05:40 wiz Exp $ */
2 1.2 thorpej
3 1.1 mycroft /*
4 1.7 wiz * Copyright (c) 1993, 1998-2001.
5 1.7 wiz * The University of Southern California/Information Sciences Institute.
6 1.1 mycroft * All rights reserved.
7 1.1 mycroft *
8 1.7 wiz * Redistribution and use in source and binary forms, with or without
9 1.7 wiz * modification, are permitted provided that the following conditions
10 1.7 wiz * are met:
11 1.7 wiz * 1. Redistributions of source code must retain the above copyright
12 1.7 wiz * notice, this list of conditions and the following disclaimer.
13 1.7 wiz * 2. Redistributions in binary form must reproduce the above copyright
14 1.7 wiz * notice, this list of conditions and the following disclaimer in the
15 1.7 wiz * documentation and/or other materials provided with the distribution.
16 1.7 wiz * 3. Neither the name of the project nor the names of its contributors
17 1.7 wiz * may be used to endorse or promote products derived from this software
18 1.7 wiz * without specific prior written permission.
19 1.1 mycroft *
20 1.7 wiz * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
21 1.7 wiz * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 1.7 wiz * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 1.7 wiz * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
24 1.7 wiz * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 1.7 wiz * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 1.7 wiz * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 1.7 wiz * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 1.7 wiz * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 1.7 wiz * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 1.7 wiz * SUCH DAMAGE.
31 1.1 mycroft */
32 1.1 mycroft
33 1.1 mycroft /* RSRR code written by Daniel Zappala, USC Information Sciences Institute,
34 1.1 mycroft * April 1995.
35 1.1 mycroft */
36 1.1 mycroft
37 1.3 mycroft /* May 1995 -- Added support for Route Change Notification */
38 1.3 mycroft
39 1.1 mycroft #ifdef RSRR
40 1.1 mycroft
41 1.1 mycroft #include "defs.h"
42 1.3 mycroft #include <sys/param.h>
43 1.3 mycroft #if (defined(BSD) && (BSD >= 199103))
44 1.3 mycroft #include <stddef.h>
45 1.3 mycroft #endif
46 1.1 mycroft
47 1.1 mycroft /* Taken from prune.c */
48 1.1 mycroft /*
49 1.1 mycroft * checks for scoped multicast addresses
50 1.1 mycroft */
51 1.1 mycroft #define GET_SCOPE(gt) { \
52 1.5 wiz int _i; \
53 1.1 mycroft if (((gt)->gt_mcastgrp & 0xff000000) == 0xef000000) \
54 1.1 mycroft for (_i = 0; _i < numvifs; _i++) \
55 1.1 mycroft if (scoped_addr(_i, (gt)->gt_mcastgrp)) \
56 1.1 mycroft VIFM_SET(_i, (gt)->gt_scope); \
57 1.1 mycroft }
58 1.1 mycroft
59 1.1 mycroft /*
60 1.1 mycroft * Exported variables.
61 1.1 mycroft */
62 1.1 mycroft int rsrr_socket; /* interface to reservation protocol */
63 1.1 mycroft
64 1.1 mycroft /*
65 1.1 mycroft * Global RSRR variables.
66 1.1 mycroft */
67 1.1 mycroft char rsrr_recv_buf[RSRR_MAX_LEN]; /* RSRR receive buffer */
68 1.1 mycroft char rsrr_send_buf[RSRR_MAX_LEN]; /* RSRR send buffer */
69 1.1 mycroft
70 1.3 mycroft struct sockaddr_un client_addr;
71 1.3 mycroft int client_length = sizeof(client_addr);
72 1.3 mycroft
73 1.3 mycroft
74 1.1 mycroft /*
75 1.1 mycroft * Procedure definitions needed internally.
76 1.1 mycroft */
77 1.5 wiz static void rsrr_accept(int recvlen);
78 1.5 wiz static void rsrr_accept_iq(void);
79 1.5 wiz static int rsrr_accept_rq(struct rsrr_rq *route_query, int flags,
80 1.5 wiz struct gtable *gt_notify);
81 1.5 wiz static int rsrr_send(int sendlen);
82 1.5 wiz static void rsrr_cache(struct gtable *gt, struct rsrr_rq *route_query);
83 1.1 mycroft
84 1.1 mycroft /* Initialize RSRR socket */
85 1.1 mycroft void
86 1.1 mycroft rsrr_init()
87 1.1 mycroft {
88 1.1 mycroft int servlen;
89 1.1 mycroft struct sockaddr_un serv_addr;
90 1.1 mycroft
91 1.4 lukem if ((rsrr_socket = socket(AF_LOCAL, SOCK_DGRAM, 0)) < 0)
92 1.7 wiz logit(LOG_ERR, errno, "Can't create RSRR socket");
93 1.1 mycroft
94 1.1 mycroft unlink(RSRR_SERV_PATH);
95 1.1 mycroft bzero((char *) &serv_addr, sizeof(serv_addr));
96 1.4 lukem serv_addr.sun_family = AF_LOCAL;
97 1.1 mycroft strcpy(serv_addr.sun_path, RSRR_SERV_PATH);
98 1.3 mycroft #if (defined(BSD) && (BSD >= 199103))
99 1.3 mycroft servlen = offsetof(struct sockaddr_un, sun_path) +
100 1.3 mycroft strlen(serv_addr.sun_path);
101 1.3 mycroft serv_addr.sun_len = servlen;
102 1.3 mycroft #else
103 1.1 mycroft servlen = sizeof(serv_addr.sun_family) + strlen(serv_addr.sun_path);
104 1.3 mycroft #endif
105 1.1 mycroft
106 1.1 mycroft if (bind(rsrr_socket, (struct sockaddr *) &serv_addr, servlen) < 0)
107 1.7 wiz logit(LOG_ERR, errno, "Can't bind RSRR socket");
108 1.1 mycroft
109 1.1 mycroft if (register_input_handler(rsrr_socket,rsrr_read) < 0)
110 1.7 wiz logit(LOG_WARNING, 0, "Couldn't register RSRR as an input handler");
111 1.1 mycroft }
112 1.1 mycroft
113 1.1 mycroft /* Read a message from the RSRR socket */
114 1.1 mycroft void
115 1.3 mycroft rsrr_read(f, rfd)
116 1.3 mycroft int f;
117 1.3 mycroft fd_set *rfd;
118 1.1 mycroft {
119 1.5 wiz int rsrr_recvlen;
120 1.5 wiz int omask;
121 1.1 mycroft
122 1.1 mycroft bzero((char *) &client_addr, sizeof(client_addr));
123 1.1 mycroft rsrr_recvlen = recvfrom(rsrr_socket, rsrr_recv_buf, sizeof(rsrr_recv_buf),
124 1.3 mycroft 0, (struct sockaddr *)&client_addr, &client_length);
125 1.1 mycroft if (rsrr_recvlen < 0) {
126 1.1 mycroft if (errno != EINTR)
127 1.7 wiz logit(LOG_ERR, errno, "RSRR recvfrom");
128 1.1 mycroft return;
129 1.1 mycroft }
130 1.1 mycroft /* Use of omask taken from main() */
131 1.1 mycroft omask = sigblock(sigmask(SIGALRM));
132 1.3 mycroft rsrr_accept(rsrr_recvlen);
133 1.1 mycroft (void)sigsetmask(omask);
134 1.1 mycroft }
135 1.1 mycroft
136 1.1 mycroft /* Accept a message from the reservation protocol and take
137 1.1 mycroft * appropriate action.
138 1.1 mycroft */
139 1.3 mycroft static void
140 1.3 mycroft rsrr_accept(recvlen)
141 1.1 mycroft int recvlen;
142 1.1 mycroft {
143 1.1 mycroft struct rsrr_header *rsrr;
144 1.1 mycroft struct rsrr_rq *route_query;
145 1.1 mycroft
146 1.1 mycroft if (recvlen < RSRR_HEADER_LEN) {
147 1.7 wiz logit(LOG_WARNING, 0,
148 1.1 mycroft "Received RSRR packet of %d bytes, which is less than min size",
149 1.1 mycroft recvlen);
150 1.1 mycroft return;
151 1.1 mycroft }
152 1.1 mycroft
153 1.1 mycroft rsrr = (struct rsrr_header *) rsrr_recv_buf;
154 1.1 mycroft
155 1.1 mycroft if (rsrr->version > RSRR_MAX_VERSION) {
156 1.7 wiz logit(LOG_WARNING, 0,
157 1.1 mycroft "Received RSRR packet version %d, which I don't understand",
158 1.1 mycroft rsrr->version);
159 1.1 mycroft return;
160 1.1 mycroft }
161 1.1 mycroft
162 1.1 mycroft switch (rsrr->version) {
163 1.1 mycroft case 1:
164 1.1 mycroft switch (rsrr->type) {
165 1.1 mycroft case RSRR_INITIAL_QUERY:
166 1.1 mycroft /* Send Initial Reply to client */
167 1.7 wiz logit(LOG_INFO, 0, "Received Initial Query\n");
168 1.3 mycroft rsrr_accept_iq();
169 1.1 mycroft break;
170 1.1 mycroft case RSRR_ROUTE_QUERY:
171 1.1 mycroft /* Check size */
172 1.1 mycroft if (recvlen < RSRR_RQ_LEN) {
173 1.7 wiz logit(LOG_WARNING, 0,
174 1.1 mycroft "Received Route Query of %d bytes, which is too small",
175 1.1 mycroft recvlen);
176 1.1 mycroft break;
177 1.1 mycroft }
178 1.1 mycroft /* Get the query */
179 1.1 mycroft route_query = (struct rsrr_rq *) (rsrr_recv_buf + RSRR_HEADER_LEN);
180 1.7 wiz logit(LOG_INFO, 0,
181 1.1 mycroft "Received Route Query for src %s grp %s notification %d",
182 1.1 mycroft inet_fmt(route_query->source_addr.s_addr, s1),
183 1.1 mycroft inet_fmt(route_query->dest_addr.s_addr,s2),
184 1.1 mycroft BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT));
185 1.1 mycroft /* Send Route Reply to client */
186 1.3 mycroft rsrr_accept_rq(route_query,rsrr->flags,NULL);
187 1.1 mycroft break;
188 1.1 mycroft default:
189 1.7 wiz logit(LOG_WARNING, 0,
190 1.1 mycroft "Received RSRR packet type %d, which I don't handle",
191 1.1 mycroft rsrr->type);
192 1.1 mycroft break;
193 1.1 mycroft }
194 1.1 mycroft break;
195 1.1 mycroft
196 1.1 mycroft default:
197 1.7 wiz logit(LOG_WARNING, 0,
198 1.1 mycroft "Received RSRR packet version %d, which I don't understand",
199 1.1 mycroft rsrr->version);
200 1.1 mycroft break;
201 1.1 mycroft }
202 1.1 mycroft }
203 1.1 mycroft
204 1.1 mycroft /* Send an Initial Reply to the reservation protocol. */
205 1.3 mycroft static void
206 1.3 mycroft rsrr_accept_iq()
207 1.1 mycroft {
208 1.1 mycroft struct rsrr_header *rsrr;
209 1.1 mycroft struct rsrr_vif *vif_list;
210 1.1 mycroft struct uvif *v;
211 1.1 mycroft int vifi, sendlen;
212 1.1 mycroft
213 1.1 mycroft /* Check for space. There should be room for plenty of vifs,
214 1.1 mycroft * but we should check anyway.
215 1.1 mycroft */
216 1.1 mycroft if (numvifs > RSRR_MAX_VIFS) {
217 1.7 wiz logit(LOG_WARNING, 0,
218 1.1 mycroft "Can't send RSRR Route Reply because %d is too many vifs %d",
219 1.1 mycroft numvifs);
220 1.1 mycroft return;
221 1.1 mycroft }
222 1.1 mycroft
223 1.1 mycroft /* Set up message */
224 1.1 mycroft rsrr = (struct rsrr_header *) rsrr_send_buf;
225 1.1 mycroft rsrr->version = 1;
226 1.1 mycroft rsrr->type = RSRR_INITIAL_REPLY;
227 1.1 mycroft rsrr->flags = 0;
228 1.1 mycroft rsrr->num = numvifs;
229 1.1 mycroft
230 1.1 mycroft vif_list = (struct rsrr_vif *) (rsrr_send_buf + RSRR_HEADER_LEN);
231 1.1 mycroft
232 1.1 mycroft /* Include the vif list. */
233 1.1 mycroft for (vifi=0, v = uvifs; vifi < numvifs; vifi++, v++) {
234 1.1 mycroft vif_list[vifi].id = vifi;
235 1.1 mycroft vif_list[vifi].status = 0;
236 1.1 mycroft if (v->uv_flags & VIFF_DISABLED)
237 1.1 mycroft BIT_SET(vif_list[vifi].status,RSRR_DISABLED_BIT);
238 1.1 mycroft vif_list[vifi].threshold = v->uv_threshold;
239 1.1 mycroft vif_list[vifi].local_addr.s_addr = v->uv_lcl_addr;
240 1.1 mycroft }
241 1.1 mycroft
242 1.1 mycroft /* Get the size. */
243 1.1 mycroft sendlen = RSRR_HEADER_LEN + numvifs*RSRR_VIF_LEN;
244 1.1 mycroft
245 1.1 mycroft /* Send it. */
246 1.7 wiz logit(LOG_INFO, 0, "Send RSRR Initial Reply");
247 1.3 mycroft rsrr_send(sendlen);
248 1.1 mycroft }
249 1.1 mycroft
250 1.3 mycroft /* Send a Route Reply to the reservation protocol. The Route Query
251 1.3 mycroft * contains the query to which we are responding. The flags contain
252 1.3 mycroft * the incoming flags from the query or, for route change
253 1.3 mycroft * notification, the flags that should be set for the reply. The
254 1.3 mycroft * kernel table entry contains the routing info to use for a route
255 1.3 mycroft * change notification.
256 1.3 mycroft */
257 1.3 mycroft static int
258 1.3 mycroft rsrr_accept_rq(route_query,flags,gt_notify)
259 1.3 mycroft struct rsrr_rq *route_query;
260 1.3 mycroft int flags;
261 1.3 mycroft struct gtable *gt_notify;
262 1.1 mycroft {
263 1.1 mycroft struct rsrr_header *rsrr;
264 1.1 mycroft struct rsrr_rr *route_reply;
265 1.1 mycroft struct gtable *gt,local_g;
266 1.1 mycroft struct rtentry *r;
267 1.1 mycroft int sendlen,i;
268 1.1 mycroft u_long mcastgrp;
269 1.1 mycroft
270 1.1 mycroft /* Set up message */
271 1.1 mycroft rsrr = (struct rsrr_header *) rsrr_send_buf;
272 1.1 mycroft rsrr->version = 1;
273 1.1 mycroft rsrr->type = RSRR_ROUTE_REPLY;
274 1.3 mycroft rsrr->flags = 0;
275 1.1 mycroft rsrr->num = 0;
276 1.1 mycroft
277 1.1 mycroft route_reply = (struct rsrr_rr *) (rsrr_send_buf + RSRR_HEADER_LEN);
278 1.1 mycroft route_reply->dest_addr.s_addr = route_query->dest_addr.s_addr;
279 1.1 mycroft route_reply->source_addr.s_addr = route_query->source_addr.s_addr;
280 1.1 mycroft route_reply->query_id = route_query->query_id;
281 1.1 mycroft
282 1.1 mycroft /* Blank routing entry for error. */
283 1.1 mycroft route_reply->in_vif = 0;
284 1.1 mycroft route_reply->reserved = 0;
285 1.1 mycroft route_reply->out_vif_bm = 0;
286 1.1 mycroft
287 1.3 mycroft /* Get the size. */
288 1.3 mycroft sendlen = RSRR_RR_LEN;
289 1.3 mycroft
290 1.3 mycroft /* If kernel table entry is defined, then we are sending a Route Reply
291 1.3 mycroft * due to a Route Change Notification event. Use the kernel table entry
292 1.3 mycroft * to supply the routing info.
293 1.3 mycroft */
294 1.3 mycroft if (gt_notify) {
295 1.3 mycroft /* Set flags */
296 1.3 mycroft rsrr->flags = flags;
297 1.3 mycroft /* Include the routing entry. */
298 1.3 mycroft route_reply->in_vif = gt_notify->gt_route->rt_parent;
299 1.3 mycroft route_reply->out_vif_bm = gt_notify->gt_grpmems;
300 1.3 mycroft
301 1.3 mycroft } else if (find_src_grp(route_query->source_addr.s_addr, 0,
302 1.3 mycroft route_query->dest_addr.s_addr)) {
303 1.3 mycroft
304 1.3 mycroft /* Found kernel entry. Code taken from add_table_entry() */
305 1.1 mycroft gt = gtp ? gtp->gt_gnext : kernel_table;
306 1.1 mycroft
307 1.1 mycroft /* Include the routing entry. */
308 1.1 mycroft route_reply->in_vif = gt->gt_route->rt_parent;
309 1.1 mycroft route_reply->out_vif_bm = gt->gt_grpmems;
310 1.3 mycroft
311 1.3 mycroft /* Cache reply if using route change notification. */
312 1.3 mycroft if BIT_TST(flags,RSRR_NOTIFICATION_BIT) {
313 1.3 mycroft rsrr_cache(gt,route_query);
314 1.3 mycroft BIT_SET(rsrr->flags,RSRR_NOTIFICATION_BIT);
315 1.3 mycroft }
316 1.1 mycroft
317 1.1 mycroft } else {
318 1.1 mycroft /* No kernel entry; use routing table. */
319 1.1 mycroft r = determine_route(route_query->source_addr.s_addr);
320 1.1 mycroft
321 1.1 mycroft if (r != NULL) {
322 1.1 mycroft /* We need to mimic what will happen if a data packet
323 1.1 mycroft * is forwarded by multicast routing -- the kernel will
324 1.1 mycroft * make an upcall and mrouted will install a route in the kernel.
325 1.1 mycroft * Our outgoing vif bitmap should reflect what that table
326 1.1 mycroft * will look like. Grab code from add_table_entry().
327 1.1 mycroft * This is gross, but it's probably better to be accurate.
328 1.1 mycroft */
329 1.1 mycroft
330 1.1 mycroft gt = &local_g;
331 1.1 mycroft mcastgrp = route_query->dest_addr.s_addr;
332 1.1 mycroft
333 1.1 mycroft gt->gt_mcastgrp = mcastgrp;
334 1.1 mycroft gt->gt_grpmems = 0;
335 1.1 mycroft gt->gt_scope = 0;
336 1.1 mycroft gt->gt_route = r;
337 1.1 mycroft
338 1.1 mycroft /* obtain the multicast group membership list */
339 1.1 mycroft for (i = 0; i < numvifs; i++) {
340 1.1 mycroft if (VIFM_ISSET(i, r->rt_children) &&
341 1.1 mycroft !(VIFM_ISSET(i, r->rt_leaves)))
342 1.1 mycroft VIFM_SET(i, gt->gt_grpmems);
343 1.1 mycroft
344 1.1 mycroft if (VIFM_ISSET(i, r->rt_leaves) && grplst_mem(i, mcastgrp))
345 1.1 mycroft VIFM_SET(i, gt->gt_grpmems);
346 1.1 mycroft }
347 1.1 mycroft
348 1.1 mycroft GET_SCOPE(gt);
349 1.1 mycroft gt->gt_grpmems &= ~gt->gt_scope;
350 1.1 mycroft
351 1.1 mycroft /* Include the routing entry. */
352 1.1 mycroft route_reply->in_vif = gt->gt_route->rt_parent;
353 1.1 mycroft route_reply->out_vif_bm = gt->gt_grpmems;
354 1.1 mycroft
355 1.1 mycroft } else {
356 1.1 mycroft /* Set error bit. */
357 1.1 mycroft BIT_SET(rsrr->flags,RSRR_ERROR_BIT);
358 1.1 mycroft }
359 1.1 mycroft }
360 1.1 mycroft
361 1.3 mycroft if (gt_notify)
362 1.7 wiz logit(LOG_INFO, 0, "Route Change: Send RSRR Route Reply");
363 1.3 mycroft
364 1.3 mycroft else
365 1.7 wiz logit(LOG_INFO, 0, "Send RSRR Route Reply");
366 1.3 mycroft
367 1.7 wiz logit(LOG_INFO, 0, "for src %s dst %s in vif %d out vif %d\n",
368 1.1 mycroft inet_fmt(route_reply->source_addr.s_addr,s1),
369 1.3 mycroft inet_fmt(route_reply->dest_addr.s_addr,s2),
370 1.1 mycroft route_reply->in_vif,route_reply->out_vif_bm);
371 1.1 mycroft
372 1.1 mycroft /* Send it. */
373 1.3 mycroft return rsrr_send(sendlen);
374 1.1 mycroft }
375 1.1 mycroft
376 1.1 mycroft /* Send an RSRR message. */
377 1.3 mycroft static int
378 1.3 mycroft rsrr_send(sendlen)
379 1.1 mycroft int sendlen;
380 1.1 mycroft {
381 1.1 mycroft int error;
382 1.1 mycroft
383 1.1 mycroft /* Send it. */
384 1.1 mycroft error = sendto(rsrr_socket, rsrr_send_buf, sendlen, 0,
385 1.3 mycroft (struct sockaddr *)&client_addr, client_length);
386 1.1 mycroft
387 1.1 mycroft /* Check for errors. */
388 1.1 mycroft if (error < 0) {
389 1.7 wiz logit(LOG_WARNING, errno, "Failed send on RSRR socket");
390 1.3 mycroft } else if (error != sendlen) {
391 1.7 wiz logit(LOG_WARNING, 0,
392 1.1 mycroft "Sent only %d out of %d bytes on RSRR socket\n", error, sendlen);
393 1.1 mycroft }
394 1.3 mycroft return error;
395 1.3 mycroft }
396 1.3 mycroft
397 1.3 mycroft /* Cache a message being sent to a client. Currently only used for
398 1.3 mycroft * caching Route Reply messages for route change notification.
399 1.3 mycroft */
400 1.3 mycroft static void
401 1.3 mycroft rsrr_cache(gt,route_query)
402 1.3 mycroft struct gtable *gt;
403 1.3 mycroft struct rsrr_rq *route_query;
404 1.3 mycroft {
405 1.3 mycroft struct rsrr_cache *rc, **rcnp;
406 1.3 mycroft struct rsrr_header *rsrr;
407 1.3 mycroft
408 1.3 mycroft rsrr = (struct rsrr_header *) rsrr_send_buf;
409 1.3 mycroft
410 1.3 mycroft rcnp = >->gt_rsrr_cache;
411 1.3 mycroft while ((rc = *rcnp) != NULL) {
412 1.3 mycroft if ((rc->route_query.source_addr.s_addr ==
413 1.3 mycroft route_query->source_addr.s_addr) &&
414 1.3 mycroft (rc->route_query.dest_addr.s_addr ==
415 1.3 mycroft route_query->dest_addr.s_addr) &&
416 1.3 mycroft (!strcmp(rc->client_addr.sun_path,client_addr.sun_path))) {
417 1.3 mycroft /* Cache entry already exists.
418 1.3 mycroft * Check if route notification bit has been cleared.
419 1.3 mycroft */
420 1.3 mycroft if (!BIT_TST(rsrr->flags,RSRR_NOTIFICATION_BIT)) {
421 1.3 mycroft /* Delete cache entry. */
422 1.3 mycroft *rcnp = rc->next;
423 1.3 mycroft free(rc);
424 1.3 mycroft } else {
425 1.3 mycroft /* Update */
426 1.3 mycroft rc->route_query.query_id = route_query->query_id;
427 1.7 wiz logit(LOG_DEBUG, 0,
428 1.3 mycroft "Update cached query id %ld from client %s\n",
429 1.3 mycroft rc->route_query.query_id, rc->client_addr.sun_path);
430 1.3 mycroft }
431 1.3 mycroft return;
432 1.3 mycroft }
433 1.3 mycroft rcnp = &rc->next;
434 1.3 mycroft }
435 1.3 mycroft
436 1.3 mycroft /* Cache entry doesn't already exist. Create one and insert at
437 1.3 mycroft * front of list.
438 1.3 mycroft */
439 1.3 mycroft rc = (struct rsrr_cache *) malloc(sizeof(struct rsrr_cache));
440 1.3 mycroft if (rc == NULL)
441 1.7 wiz logit(LOG_ERR, 0, "ran out of memory");
442 1.3 mycroft rc->route_query.source_addr.s_addr = route_query->source_addr.s_addr;
443 1.3 mycroft rc->route_query.dest_addr.s_addr = route_query->dest_addr.s_addr;
444 1.3 mycroft rc->route_query.query_id = route_query->query_id;
445 1.3 mycroft strcpy(rc->client_addr.sun_path, client_addr.sun_path);
446 1.3 mycroft rc->client_length = client_length;
447 1.3 mycroft rc->next = gt->gt_rsrr_cache;
448 1.3 mycroft gt->gt_rsrr_cache = rc;
449 1.7 wiz logit(LOG_DEBUG, 0, "Cached query id %ld from client %s\n",
450 1.3 mycroft rc->route_query.query_id,rc->client_addr.sun_path);
451 1.3 mycroft }
452 1.3 mycroft
453 1.3 mycroft /* Send all the messages in the cache. Currently this is used to send
454 1.3 mycroft * all the cached Route Reply messages for route change notification.
455 1.3 mycroft */
456 1.3 mycroft void
457 1.3 mycroft rsrr_cache_send(gt,notify)
458 1.3 mycroft struct gtable *gt;
459 1.3 mycroft int notify;
460 1.3 mycroft {
461 1.3 mycroft struct rsrr_cache *rc, **rcnp;
462 1.3 mycroft int flags = 0;
463 1.3 mycroft
464 1.3 mycroft if (notify)
465 1.3 mycroft BIT_SET(flags,RSRR_NOTIFICATION_BIT);
466 1.3 mycroft
467 1.3 mycroft rcnp = >->gt_rsrr_cache;
468 1.3 mycroft while ((rc = *rcnp) != NULL) {
469 1.3 mycroft if (rsrr_accept_rq(&rc->route_query,flags,gt) < 0) {
470 1.7 wiz logit(LOG_DEBUG, 0, "Deleting cached query id %ld from client %s\n",
471 1.3 mycroft rc->route_query.query_id,rc->client_addr.sun_path);
472 1.3 mycroft /* Delete cache entry. */
473 1.3 mycroft *rcnp = rc->next;
474 1.3 mycroft free(rc);
475 1.3 mycroft } else {
476 1.3 mycroft rcnp = &rc->next;
477 1.3 mycroft }
478 1.3 mycroft }
479 1.3 mycroft }
480 1.3 mycroft
481 1.3 mycroft /* Clean the cache by deleting all entries. */
482 1.3 mycroft void
483 1.3 mycroft rsrr_cache_clean(gt)
484 1.3 mycroft struct gtable *gt;
485 1.3 mycroft {
486 1.3 mycroft struct rsrr_cache *rc,*rc_next;
487 1.3 mycroft
488 1.3 mycroft printf("cleaning cache for group %s\n",inet_fmt(gt->gt_mcastgrp, s1));
489 1.3 mycroft rc = gt->gt_rsrr_cache;
490 1.3 mycroft while (rc) {
491 1.3 mycroft rc_next = rc->next;
492 1.3 mycroft free(rc);
493 1.3 mycroft rc = rc_next;
494 1.3 mycroft }
495 1.3 mycroft gt->gt_rsrr_cache = NULL;
496 1.1 mycroft }
497 1.1 mycroft
498 1.1 mycroft void
499 1.1 mycroft rsrr_clean()
500 1.1 mycroft {
501 1.1 mycroft unlink(RSRR_SERV_PATH);
502 1.1 mycroft }
503 1.1 mycroft
504 1.3 mycroft #endif /* RSRR */
505