xref: /openbsd/usr.sbin/bgpd/rtr_proto.c (revision 9dad7388)
1 /*	$OpenBSD: rtr_proto.c,v 1.28 2024/01/10 16:08:36 claudio Exp $ */
2 
3 /*
4  * Copyright (c) 2020 Claudio Jeker <claudio@openbsd.org>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18 #include <sys/tree.h>
19 #include <errno.h>
20 #include <stdint.h>
21 #include <poll.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
25 #include <unistd.h>
26 
27 #include "bgpd.h"
28 #include "session.h"
29 #include "log.h"
30 
31 struct rtr_header {
32 	uint8_t		version;
33 	uint8_t		type;
34 	uint16_t	session_id; /* or error code */
35 	uint32_t	length;
36 } __packed;
37 
38 #define RTR_MAX_VERSION		2
39 #define RTR_MAX_LEN		2048
40 #define RTR_DEFAULT_REFRESH	3600
41 #define RTR_DEFAULT_RETRY	600
42 #define RTR_DEFAULT_EXPIRE	7200
43 #define RTR_DEFAULT_ACTIVE	60
44 
45 enum rtr_pdu_type {
46 	SERIAL_NOTIFY = 0,
47 	SERIAL_QUERY,
48 	RESET_QUERY,
49 	CACHE_RESPONSE,
50 	IPV4_PREFIX,
51 	IPV6_PREFIX = 6,
52 	END_OF_DATA = 7,
53 	CACHE_RESET = 8,
54 	ROUTER_KEY = 9,
55 	ERROR_REPORT = 10,
56 	ASPA = 11,
57 };
58 
59 struct rtr_notify {
60 	struct rtr_header	hdr;
61 	uint32_t		serial;
62 } __packed;
63 
64 struct rtr_query {
65 	struct rtr_header	hdr;
66 	uint32_t		serial;
67 } __packed;
68 
69 struct rtr_reset {
70 	struct rtr_header	hdr;
71 } __packed;
72 
73 struct rtr_response {
74 	struct rtr_header	hdr;
75 } __packed;
76 
77 #define FLAG_ANNOUNCE	0x1
78 #define FLAG_MASK	FLAG_ANNOUNCE
79 struct rtr_ipv4 {
80 	struct rtr_header	hdr;
81 	uint8_t			flags;
82 	uint8_t			prefixlen;
83 	uint8_t			maxlen;
84 	uint8_t			zero;
85 	uint32_t		prefix;
86 	uint32_t		asnum;
87 } __packed;
88 
89 struct rtr_ipv6 {
90 	struct rtr_header	hdr;
91 	uint8_t			flags;
92 	uint8_t			prefixlen;
93 	uint8_t			maxlen;
94 	uint8_t			zero;
95 	uint32_t		prefix[4];
96 	uint32_t		asnum;
97 } __packed;
98 
99 struct rtr_routerkey {
100 	struct rtr_header	hdr;
101 	uint8_t			ski[20];
102 	uint32_t		asnum;
103 	/* followed by Subject Public Key Info */
104 } __packed;
105 
106 #define FLAG_AFI_V6	0x1
107 #define FLAG_AFI_MASK	FLAG_AFI_V6
108 struct rtr_aspa {
109 	struct rtr_header	hdr;
110 	uint8_t			flags;
111 	uint8_t			afi_flags;
112 	uint16_t		cnt;
113 	uint32_t		cas;
114 	/* array of spas with cnt elements follows */
115 } __packed;
116 
117 struct rtr_endofdata {
118 	struct rtr_header	hdr;
119 	uint32_t		serial;
120 	uint32_t		refresh;
121 	uint32_t		retry;
122 	uint32_t		expire;
123 } __packed;
124 
125 struct rtr_endofdata_v0 {
126 	struct rtr_header	hdr;
127 	uint32_t		serial;
128 } __packed;
129 
130 enum rtr_event {
131 	RTR_EVNT_START,
132 	RTR_EVNT_CON_OPEN,
133 	RTR_EVNT_CON_CLOSE,
134 	RTR_EVNT_TIMER_REFRESH,
135 	RTR_EVNT_TIMER_RETRY,
136 	RTR_EVNT_TIMER_EXPIRE,
137 	RTR_EVNT_TIMER_ACTIVE,
138 	RTR_EVNT_SEND_ERROR,
139 	RTR_EVNT_SERIAL_NOTIFY,
140 	RTR_EVNT_CACHE_RESPONSE,
141 	RTR_EVNT_END_OF_DATA,
142 	RTR_EVNT_CACHE_RESET,
143 	RTR_EVNT_NO_DATA,
144 	RTR_EVNT_RESET_AND_CLOSE,
145 	RTR_EVNT_UNSUPP_PROTO_VERSION,
146 	RTR_EVNT_NEGOTIATION_DONE,
147 };
148 
149 static const char *rtr_eventnames[] = {
150 	"start",
151 	"connection open",
152 	"connection closed",
153 	"refresh timer expired",
154 	"retry timer expired",
155 	"expire timer expired",
156 	"activity timer expired",
157 	"sent error",
158 	"serial notify received",
159 	"cache response received",
160 	"end of data received",
161 	"cache reset received",
162 	"no data",
163 	"connection closed with reset",
164 	"unsupported protocol version",
165 	"negotiation done",
166 };
167 
168 enum rtr_state {
169 	RTR_STATE_CLOSED,
170 	RTR_STATE_ERROR,
171 	/* sessions with a state below this line will poll for incoming data */
172 	RTR_STATE_ESTABLISHED,
173 	RTR_STATE_EXCHANGE,
174 	RTR_STATE_NEGOTIATION,
175 };
176 
177 static const char *rtr_statenames[] = {
178 	"closed",
179 	"error",
180 	"established",
181 	"exchange",
182 	"negotiation",
183 };
184 
185 struct rtr_session {
186 	TAILQ_ENTRY(rtr_session)	entry;
187 	char				descr[PEER_DESCR_LEN];
188 	struct roa_tree			roa_set;
189 	struct aspa_tree		aspa;
190 	struct aspa_tree		aspa_oldv6;
191 	struct ibuf_read		r;
192 	struct msgbuf			w;
193 	struct timer_head		timers;
194 	uint32_t			id;		/* rtr_config id */
195 	uint32_t			serial;
196 	uint32_t			refresh;
197 	uint32_t			retry;
198 	uint32_t			expire;
199 	uint32_t			active;
200 	int				session_id;
201 	int				fd;
202 	int				active_lock;
203 	enum rtr_state			state;
204 	enum reconf_action		reconf_action;
205 	enum rtr_error			last_sent_error;
206 	enum rtr_error			last_recv_error;
207 	char				last_sent_msg[REASON_LEN];
208 	char				last_recv_msg[REASON_LEN];
209 	uint8_t				version;
210 };
211 
212 TAILQ_HEAD(, rtr_session) rtrs = TAILQ_HEAD_INITIALIZER(rtrs);
213 
214 static void	rtr_fsm(struct rtr_session *, enum rtr_event);
215 
216 static const char *
217 log_rtr(struct rtr_session *rs)
218 {
219 	return rs->descr;
220 }
221 
222 static const char *
223 log_rtr_type(enum rtr_pdu_type type)
224 {
225 	static char buf[20];
226 
227 	switch (type) {
228 	case SERIAL_NOTIFY:
229 		return "serial notify";
230 	case SERIAL_QUERY:
231 		return "serial query";
232 	case RESET_QUERY:
233 		return "reset query";
234 	case CACHE_RESPONSE:
235 		return "cache response";
236 	case IPV4_PREFIX:
237 		return "IPv4 prefix";
238 	case IPV6_PREFIX:
239 		return "IPv6 prefix";
240 	case END_OF_DATA:
241 		return "end of data";
242 	case CACHE_RESET:
243 		return "cache reset";
244 	case ROUTER_KEY:
245 		return "router key";
246 	case ERROR_REPORT:
247 		return "error report";
248 	case ASPA:
249 		return "aspa";
250 	default:
251 		snprintf(buf, sizeof(buf), "unknown %u", type);
252 		return buf;
253 	}
254 };
255 
256 static void
257 rtr_reset_cache(struct rtr_session *rs)
258 {
259 	/* reset session */
260 	rs->session_id = -1;
261 	timer_stop(&rs->timers, Timer_Rtr_Expire);
262 	free_roatree(&rs->roa_set);
263 	free_aspatree(&rs->aspa);
264 	free_aspatree(&rs->aspa_oldv6);
265 }
266 
267 static struct ibuf *
268 rtr_newmsg(struct rtr_session *rs, enum rtr_pdu_type type, uint32_t len,
269     uint16_t session_id)
270 {
271 	struct ibuf *buf;
272 	int saved_errno;
273 
274 	if (len > RTR_MAX_LEN) {
275 		errno = ERANGE;
276 		return NULL;
277 	}
278 	len += sizeof(struct rtr_header);
279 	if ((buf = ibuf_open(len)) == NULL)
280 		goto fail;
281 	if (ibuf_add_n8(buf, rs->version) == -1)
282 		goto fail;
283 	if (ibuf_add_n8(buf, type) == -1)
284 		goto fail;
285 	if (ibuf_add_n16(buf, session_id) == -1)
286 		goto fail;
287 	if (ibuf_add_n32(buf, len) == -1)
288 		goto fail;
289 
290 	return buf;
291 
292  fail:
293 	saved_errno = errno;
294 	ibuf_free(buf);
295 	errno = saved_errno;
296 	return NULL;
297 }
298 
299 static void rtr_send_error(struct rtr_session *, struct ibuf *, enum rtr_error,
300     const char *, ...) __attribute__((__format__ (printf, 4, 5)));
301 
302 /*
303  * Try to send an error PDU to cache, put connection into error
304  * state.
305  */
306 static void
307 rtr_send_error(struct rtr_session *rs, struct ibuf *pdu, enum rtr_error err,
308     const char *fmt, ...)
309 {
310 	struct ibuf *buf;
311 	va_list ap;
312 	size_t len = 0, mlen = 0;
313 
314 	rs->last_sent_error = err;
315 	memset(rs->last_sent_msg, 0, sizeof(rs->last_sent_msg));
316 	if (fmt != NULL) {
317 		va_start(ap, fmt);
318 		vsnprintf(rs->last_sent_msg, sizeof(rs->last_sent_msg),
319 		    fmt, ap);
320 		mlen = strlen(rs->last_sent_msg);
321 		va_end(ap);
322 	}
323 
324 	log_warnx("rtr %s: sending error: %s%s%s", log_rtr(rs),
325 	    log_rtr_error(err), mlen > 0 ? ": " : "", rs->last_sent_msg);
326 
327 	if (pdu != NULL) {
328 		ibuf_rewind(pdu);
329 		len = ibuf_size(pdu);
330 	}
331 
332 	buf = rtr_newmsg(rs, ERROR_REPORT, 2 * sizeof(uint32_t) + len + mlen,
333 	    err);
334 	if (buf == NULL)
335 		goto fail;
336 	if (ibuf_add_n32(buf, len) == -1)
337 		goto fail;
338 	if (pdu != NULL) {
339 		if (ibuf_add_ibuf(buf, pdu) == -1)
340 			goto fail;
341 	}
342 	if (ibuf_add_n32(buf, mlen) == -1)
343 		goto fail;
344 	if (ibuf_add(buf, rs->last_sent_msg, mlen) == -1)
345 		goto fail;
346 	ibuf_close(&rs->w, buf);
347 
348 	rtr_fsm(rs, RTR_EVNT_SEND_ERROR);
349 	return;
350 
351  fail:
352 	log_warn("rtr %s: send error report", log_rtr(rs));
353 	ibuf_free(buf);
354 }
355 
356 static void
357 rtr_send_reset_query(struct rtr_session *rs)
358 {
359 	struct ibuf *buf;
360 
361 	buf = rtr_newmsg(rs, RESET_QUERY, 0, 0);
362 	if (buf == NULL)
363 		goto fail;
364 	ibuf_close(&rs->w, buf);
365 	return;
366 
367  fail:
368 	rtr_send_error(rs, NULL, INTERNAL_ERROR,
369 	    "send %s: %s", log_rtr_type(RESET_QUERY), strerror(errno));
370 	ibuf_free(buf);
371 }
372 
373 static void
374 rtr_send_serial_query(struct rtr_session *rs)
375 {
376 	struct ibuf *buf;
377 
378 	buf = rtr_newmsg(rs, SERIAL_QUERY, sizeof(uint32_t), rs->session_id);
379 	if (buf == NULL)
380 		goto fail;
381 	if (ibuf_add_n32(buf, rs->serial) == -1)
382 		goto fail;
383 	ibuf_close(&rs->w, buf);
384 	return;
385 
386  fail:
387 	rtr_send_error(rs, NULL, INTERNAL_ERROR,
388 	    "send %s: %s", log_rtr_type(SERIAL_QUERY), strerror(errno));
389 	ibuf_free(buf);
390 }
391 
392 /*
393  * Check the session_id of the rtr_header to match the expected value.
394  * Returns -1 on failure and 0 on success.
395  */
396 static int
397 rtr_check_session_id(struct rtr_session *rs, uint16_t session_id,
398     struct rtr_header *rh, struct ibuf *pdu)
399 {
400 	if (session_id != ntohs(rh->session_id)) {
401 		rtr_send_error(rs, pdu, CORRUPT_DATA,
402 		    "%s: bad session_id %d (expected %d)",
403 		    log_rtr_type(rh->type), ntohs(rh->session_id), session_id);
404 		return -1;
405 	}
406 	return 0;
407 }
408 
409 /*
410  * Parse the common rtr header (first 8 bytes) including the
411  * included length field.
412  * Returns -1 on failure. On success msgtype and msglen are set
413  * and the function return 0.
414  */
415 static int
416 rtr_parse_header(struct rtr_session *rs, struct ibuf *hdr,
417     size_t *msglen, enum rtr_pdu_type *msgtype)
418 {
419 	struct rtr_header rh;
420 	size_t len;
421 
422 	if (ibuf_get(hdr, &rh, sizeof(rh)) == -1)
423 		fatal("%s: ibuf_get", __func__);
424 
425 	len = ntohl(rh.length);
426 
427 	if (len > RTR_MAX_LEN) {
428 		rtr_send_error(rs, hdr, CORRUPT_DATA, "%s: too big: %zu bytes",
429 		    log_rtr_type(rh.type), len);
430 		return -1;
431 	}
432 
433 	if (rs->state == RTR_STATE_NEGOTIATION) {
434 		switch (rh.type) {
435 		case CACHE_RESPONSE:
436 		case CACHE_RESET:
437 		case ERROR_REPORT:
438 			if (rh.version < rs->version)
439 				rs->version = rh.version;
440 			rtr_fsm(rs, RTR_EVNT_NEGOTIATION_DONE);
441 			break;
442 		case SERIAL_NOTIFY:
443 			/* ignore SERIAL_NOTIFY */
444 			break;
445 		default:
446 			rtr_send_error(rs, hdr, CORRUPT_DATA,
447 			    "%s: out of context", log_rtr_type(rh.type));
448 			return -1;
449 		}
450 	} else if (rh.version != rs->version && rh.type != ERROR_REPORT) {
451 		goto badversion;
452 	}
453 
454 	switch (rh.type) {
455 	case SERIAL_NOTIFY:
456 		if (len != sizeof(struct rtr_notify))
457 			goto badlen;
458 		break;
459 	case CACHE_RESPONSE:
460 		if (len != sizeof(struct rtr_response))
461 			goto badlen;
462 		break;
463 	case IPV4_PREFIX:
464 		if (len != sizeof(struct rtr_ipv4))
465 			goto badlen;
466 		break;
467 	case IPV6_PREFIX:
468 		if (len != sizeof(struct rtr_ipv6))
469 			goto badlen;
470 		break;
471 	case END_OF_DATA:
472 		if (rs->version == 0) {
473 			if (len != sizeof(struct rtr_endofdata_v0))
474 				goto badlen;
475 		} else {
476 			if (len != sizeof(struct rtr_endofdata))
477 				goto badlen;
478 		}
479 		break;
480 	case CACHE_RESET:
481 		if (len != sizeof(struct rtr_reset))
482 			goto badlen;
483 		break;
484 	case ROUTER_KEY:
485 		if (rs->version < 1)
486 			goto badversion;
487 		if (len < sizeof(struct rtr_routerkey))
488 			goto badlen;
489 		break;
490 	case ERROR_REPORT:
491 		if (len < 16)
492 			goto badlen;
493 		break;
494 	case ASPA:
495 		if (rs->version < 2)
496 			goto badversion;
497 		if (len < sizeof(struct rtr_aspa) || (len % 4) != 0)
498 			goto badlen;
499 		break;
500 	default:
501 		rtr_send_error(rs, hdr, UNSUPP_PDU_TYPE, "type %s",
502 		    log_rtr_type(rh.type));
503 		return -1;
504 	}
505 
506 	*msglen = len;
507 	*msgtype = rh.type;
508 
509 	return 0;
510 
511  badlen:
512 	rtr_send_error(rs, hdr, CORRUPT_DATA, "%s: bad length: %zu bytes",
513 	    log_rtr_type(rh.type), len);
514 	return -1;
515 
516  badversion:
517 	rtr_send_error(rs, hdr, UNEXP_PROTOCOL_VERS, "%s: version %d",
518 	    log_rtr_type(rh.type), rh.version);
519 	return -1;
520 }
521 
522 static int
523 rtr_parse_notify(struct rtr_session *rs, struct ibuf *pdu)
524 {
525 	struct rtr_notify notify;
526 
527 	/* ignore SERIAL_NOTIFY during startup */
528 	if (rs->state == RTR_STATE_NEGOTIATION)
529 		return 0;
530 
531 	if (ibuf_get(pdu, &notify, sizeof(notify)) == -1)
532 		goto badlen;
533 
534 	if (rtr_check_session_id(rs, rs->session_id, &notify.hdr, pdu) == -1)
535 		return -1;
536 
537 	if (rs->state != RTR_STATE_ESTABLISHED) {
538 		log_warnx("rtr %s: received %s: while in state %s (ignored)",
539 		    log_rtr(rs), log_rtr_type(SERIAL_NOTIFY),
540 		    rtr_statenames[rs->state]);
541 		return 0;
542 	}
543 
544 	rtr_fsm(rs, RTR_EVNT_SERIAL_NOTIFY);
545 	return 0;
546 
547  badlen:
548 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
549 	    log_rtr_type(SERIAL_NOTIFY));
550 	return -1;
551 }
552 
553 static int
554 rtr_parse_cache_response(struct rtr_session *rs, struct ibuf *pdu)
555 {
556 	struct rtr_response resp;
557 
558 	if (ibuf_get(pdu, &resp, sizeof(resp)) == -1)
559 		goto badlen;
560 
561 	/* set session_id if not yet happened */
562 	if (rs->session_id == -1)
563 		rs->session_id = ntohs(resp.hdr.session_id);
564 
565 	if (rtr_check_session_id(rs, rs->session_id, &resp.hdr, pdu) == -1)
566 		return -1;
567 
568 	if (rs->state != RTR_STATE_ESTABLISHED) {
569 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
570 		    log_rtr_type(CACHE_RESPONSE));
571 		return -1;
572 	}
573 
574 	rtr_fsm(rs, RTR_EVNT_CACHE_RESPONSE);
575 	return 0;
576 
577  badlen:
578 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
579 	    log_rtr_type(CACHE_RESPONSE));
580 	return -1;
581 }
582 
583 static int
584 rtr_parse_ipv4_prefix(struct rtr_session *rs, struct ibuf *pdu)
585 {
586 	struct rtr_ipv4 ip4;
587 	struct roa *roa;
588 
589 	if (ibuf_get(pdu, &ip4, sizeof(ip4)) == -1)
590 		goto badlen;
591 
592 	if (rtr_check_session_id(rs, 0, &ip4.hdr, pdu) == -1)
593 		return -1;
594 
595 	if (rs->state != RTR_STATE_EXCHANGE) {
596 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
597 		    log_rtr_type(IPV4_PREFIX));
598 		return -1;
599 	}
600 
601 	if (ip4.prefixlen > 32 || ip4.maxlen > 32 ||
602 	    ip4.prefixlen > ip4.maxlen) {
603 		rtr_send_error(rs, pdu, CORRUPT_DATA,
604 		    "%s: bad prefixlen / maxlen", log_rtr_type(IPV4_PREFIX));
605 		return -1;
606 	}
607 
608 	if ((roa = calloc(1, sizeof(*roa))) == NULL) {
609 		rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory");
610 		return -1;
611 	}
612 	roa->aid = AID_INET;
613 	roa->prefixlen = ip4.prefixlen;
614 	roa->maxlen = ip4.maxlen;
615 	roa->asnum = ntohl(ip4.asnum);
616 	roa->prefix.inet.s_addr = ip4.prefix;
617 
618 	if (ip4.flags & FLAG_ANNOUNCE) {
619 		if (RB_INSERT(roa_tree, &rs->roa_set, roa) != NULL) {
620 			rtr_send_error(rs, pdu, DUP_REC_RECV, "%s %s",
621 			    log_rtr_type(IPV4_PREFIX), log_roa(roa));
622 			free(roa);
623 			return -1;
624 		}
625 	} else {
626 		struct roa *r;
627 
628 		r = RB_FIND(roa_tree, &rs->roa_set, roa);
629 		if (r == NULL) {
630 			rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s",
631 			    log_rtr_type(IPV4_PREFIX), log_roa(roa));
632 			free(roa);
633 			return -1;
634 		}
635 		RB_REMOVE(roa_tree, &rs->roa_set, r);
636 		free(r);
637 		free(roa);
638 	}
639 
640 	return 0;
641 
642  badlen:
643 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
644 	    log_rtr_type(IPV4_PREFIX));
645 	return -1;
646 }
647 
648 static int
649 rtr_parse_ipv6_prefix(struct rtr_session *rs, struct ibuf *pdu)
650 {
651 	struct rtr_ipv6 ip6;
652 	struct roa *roa;
653 
654 	if (ibuf_get(pdu, &ip6, sizeof(ip6)) == -1)
655 		goto badlen;
656 
657 	if (rtr_check_session_id(rs, 0, &ip6.hdr, pdu) == -1)
658 		return -1;
659 
660 	if (rs->state != RTR_STATE_EXCHANGE) {
661 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
662 		    log_rtr_type(IPV6_PREFIX));
663 		return -1;
664 	}
665 
666 	if (ip6.prefixlen > 128 || ip6.maxlen > 128 ||
667 	    ip6.prefixlen > ip6.maxlen) {
668 		rtr_send_error(rs, pdu, CORRUPT_DATA,
669 		    "%s: bad prefixlen / maxlen", log_rtr_type(IPV6_PREFIX));
670 		return -1;
671 	}
672 
673 	if ((roa = calloc(1, sizeof(*roa))) == NULL) {
674 		rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory");
675 		return -1;
676 	}
677 	roa->aid = AID_INET6;
678 	roa->prefixlen = ip6.prefixlen;
679 	roa->maxlen = ip6.maxlen;
680 	roa->asnum = ntohl(ip6.asnum);
681 	memcpy(&roa->prefix.inet6, ip6.prefix, sizeof(roa->prefix.inet6));
682 
683 	if (ip6.flags & FLAG_ANNOUNCE) {
684 		if (RB_INSERT(roa_tree, &rs->roa_set, roa) != NULL) {
685 			rtr_send_error(rs, pdu, DUP_REC_RECV, "%s %s",
686 			    log_rtr_type(IPV6_PREFIX), log_roa(roa));
687 			free(roa);
688 			return -1;
689 		}
690 	} else {
691 		struct roa *r;
692 
693 		r = RB_FIND(roa_tree, &rs->roa_set, roa);
694 		if (r == NULL) {
695 			rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s",
696 			    log_rtr_type(IPV6_PREFIX), log_roa(roa));
697 			free(roa);
698 			return -1;
699 		}
700 		RB_REMOVE(roa_tree, &rs->roa_set, r);
701 		free(r);
702 		free(roa);
703 	}
704 	return 0;
705 
706  badlen:
707 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
708 	    log_rtr_type(IPV6_PREFIX));
709 	return -1;
710 }
711 
712 static int
713 rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu)
714 {
715 	struct rtr_aspa rtr_aspa;
716 	struct aspa_tree *aspatree;
717 	struct aspa_set *aspa, *a;
718 	uint16_t cnt, i;
719 
720 	if (ibuf_get(pdu, &rtr_aspa, sizeof(rtr_aspa)) == -1)
721 		goto badlen;
722 
723 	cnt = ntohs(rtr_aspa.cnt);
724 	if (ibuf_size(pdu) != cnt * sizeof(uint32_t))
725 		goto badlen;
726 
727 	if (rs->state != RTR_STATE_EXCHANGE) {
728 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
729 		    log_rtr_type(ASPA));
730 		return -1;
731 	}
732 
733 	if (rtr_aspa.afi_flags & FLAG_AFI_V6) {
734 		aspatree = &rs->aspa_oldv6;
735 	} else {
736 		aspatree = &rs->aspa;
737 	}
738 
739 	/* create aspa_set entry from the rtr aspa pdu */
740 	if ((aspa = calloc(1, sizeof(*aspa))) == NULL) {
741 		rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory");
742 		return -1;
743 	}
744 	aspa->as = ntohl(rtr_aspa.cas);
745 	aspa->num = cnt;
746 	if (cnt > 0) {
747 		if ((aspa->tas = calloc(cnt, sizeof(uint32_t))) == NULL) {
748 			free_aspa(aspa);
749 			rtr_send_error(rs, NULL, INTERNAL_ERROR,
750 			    "out of memory");
751 			return -1;
752 		}
753 		for (i = 0; i < cnt; i++) {
754 			if (ibuf_get_n32(pdu, &aspa->tas[i]) == -1)
755 				goto badlen;
756 		}
757 	}
758 
759 	if (rtr_aspa.flags & FLAG_ANNOUNCE) {
760 		a = RB_INSERT(aspa_tree, aspatree, aspa);
761 		if (a != NULL) {
762 			RB_REMOVE(aspa_tree, aspatree, a);
763 			free_aspa(a);
764 
765 			if (RB_INSERT(aspa_tree, aspatree, aspa) != NULL) {
766 				rtr_send_error(rs, NULL, INTERNAL_ERROR,
767 				    "corrupt aspa tree");
768 				free_aspa(aspa);
769 				return -1;
770 			}
771 		}
772 	} else {
773 		a = RB_FIND(aspa_tree, aspatree, aspa);
774 		if (a == NULL) {
775 			rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s",
776 			    log_rtr_type(ASPA), log_aspa(aspa));
777 			free_aspa(aspa);
778 			return -1;
779 		}
780 		RB_REMOVE(aspa_tree, aspatree, a);
781 		free_aspa(a);
782 		free_aspa(aspa);
783 	}
784 
785 	return 0;
786 
787  badlen:
788 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
789 	    log_rtr_type(ASPA));
790 	return -1;
791 }
792 
793 static int
794 rtr_parse_end_of_data_v0(struct rtr_session *rs, struct ibuf *pdu)
795 {
796 	struct rtr_endofdata_v0 eod;
797 
798 	if (ibuf_get(pdu, &eod, sizeof(eod)) == -1)
799 		goto badlen;
800 
801 	if (rtr_check_session_id(rs, rs->session_id, &eod.hdr, pdu) == -1)
802 		return -1;
803 
804 	if (rs->state != RTR_STATE_EXCHANGE) {
805 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
806 		    log_rtr_type(END_OF_DATA));
807 		return -1;
808 	}
809 
810 	rs->serial = ntohl(eod.serial);
811 
812 	rtr_fsm(rs, RTR_EVNT_END_OF_DATA);
813 	return 0;
814 
815  badlen:
816 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
817 	    log_rtr_type(END_OF_DATA));
818 	return -1;
819 }
820 
821 static int
822 rtr_parse_end_of_data(struct rtr_session *rs, struct ibuf *pdu)
823 {
824 	struct rtr_endofdata eod;
825 	uint32_t t;
826 
827 	/* version 0 does not have the timing values */
828 	if (rs->version == 0)
829 		return rtr_parse_end_of_data_v0(rs, pdu);
830 
831 	if (ibuf_get(pdu, &eod, sizeof(eod)) == -1)
832 		goto badlen;
833 
834 	if (rtr_check_session_id(rs, rs->session_id, &eod.hdr, pdu) == -1)
835 		return -1;
836 
837 	if (rs->state != RTR_STATE_EXCHANGE) {
838 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
839 		    log_rtr_type(END_OF_DATA));
840 		return -1;
841 	}
842 
843 	rs->serial = ntohl(eod.serial);
844 	/* validate timer values to be in the right range */
845 	t = ntohl(eod.refresh);
846 	if (t < 1 || t > 86400)
847 		goto bad;
848 	rs->refresh = t;
849 	t = ntohl(eod.retry);
850 	if (t < 1 || t > 7200)
851 		goto bad;
852 	rs->retry = t;
853 	t = ntohl(eod.expire);
854 	if (t < 600 || t > 172800)
855 		goto bad;
856 	if (t <= rs->retry || t <= rs->refresh)
857 		goto bad;
858 	rs->expire = t;
859 
860 	rtr_fsm(rs, RTR_EVNT_END_OF_DATA);
861 	return 0;
862 
863 bad:
864 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad timeout values",
865 	    log_rtr_type(END_OF_DATA));
866 	return -1;
867 
868 badlen:
869 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
870 	    log_rtr_type(END_OF_DATA));
871 	return -1;
872 }
873 
874 static int
875 rtr_parse_cache_reset(struct rtr_session *rs, struct ibuf *pdu)
876 {
877 	struct rtr_reset reset;
878 
879 	if (ibuf_get(pdu, &reset, sizeof(reset)) == -1)
880 		goto badlen;
881 
882 	if (rtr_check_session_id(rs, 0, &reset.hdr, pdu) == -1)
883 		return -1;
884 
885 	if (rs->state != RTR_STATE_ESTABLISHED) {
886 		rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context",
887 		    log_rtr_type(CACHE_RESET));
888 		return -1;
889 	}
890 
891 	rtr_fsm(rs, RTR_EVNT_CACHE_RESET);
892 	return 0;
893 
894  badlen:
895 	rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length",
896 	    log_rtr_type(CACHE_RESET));
897 	return -1;
898 }
899 
900 static char *
901 ibuf_get_string(struct ibuf *buf, size_t len)
902 {
903 	char *str;
904 
905 	if (ibuf_size(buf) < len) {
906 		errno = EBADMSG;
907 		return (NULL);
908 	}
909 	str = strndup(ibuf_data(buf), len);
910 	if (str == NULL)
911 		return (NULL);
912 	ibuf_skip(buf, len);
913 	return (str);
914 }
915 
916 /*
917  * Parse an Error Response message. This function behaves a bit different
918  * from other parse functions since on error the connection needs to be
919  * dropped without sending an error response back.
920  */
921 static int
922 rtr_parse_error(struct rtr_session *rs, struct ibuf *pdu)
923 {
924 	struct rtr_header rh;
925 	struct ibuf err_pdu;
926 	uint32_t pdu_len, msg_len;
927 	char *str = NULL;
928 	uint16_t errcode;
929 	int rv = -1;
930 
931 	if (ibuf_get(pdu, &rh, sizeof(rh)) == -1)
932 		goto fail;
933 	errcode = ntohs(rh.session_id);
934 
935 	if (ibuf_get_n32(pdu, &pdu_len) == -1)
936 		goto fail;
937 
938 	/* for now just ignore the embedded pdu */
939 	if (ibuf_get_ibuf(pdu, pdu_len, &err_pdu) == -1)
940 		goto fail;
941 
942 	if (ibuf_get_n32(pdu, &msg_len) == -1)
943 		goto fail;
944 
945 	/* optional error msg */
946 	if (msg_len != 0)
947 		if ((str = ibuf_get_string(pdu, msg_len)) == NULL)
948 			goto fail;
949 
950 	log_warnx("rtr %s: received error: %s%s%s", log_rtr(rs),
951 	    log_rtr_error(errcode), str ? ": " : "", str ? str : "");
952 
953 	if (errcode == NO_DATA_AVAILABLE) {
954 		rtr_fsm(rs, RTR_EVNT_NO_DATA);
955 		rv = 0;
956 	} else if (errcode == UNSUPP_PROTOCOL_VERS)
957 		rtr_fsm(rs, RTR_EVNT_UNSUPP_PROTO_VERSION);
958 	else
959 		rtr_fsm(rs, RTR_EVNT_RESET_AND_CLOSE);
960 
961 	rs->last_recv_error = errcode;
962 	if (str)
963 		strlcpy(rs->last_recv_msg, str, sizeof(rs->last_recv_msg));
964 	else
965 		memset(rs->last_recv_msg, 0, sizeof(rs->last_recv_msg));
966 
967 	free(str);
968 	return rv;
969 
970  fail:
971 	log_warnx("rtr %s: received %s: bad encoding", log_rtr(rs),
972 	    log_rtr_type(ERROR_REPORT));
973 	rtr_fsm(rs, RTR_EVNT_RESET_AND_CLOSE);
974 	return -1;
975 }
976 
977 /*
978  * Try to process received rtr message, it is possible that not a full
979  * message is in the buffer. In that case stop, once new data is available
980  * a retry will be done.
981  */
982 static void
983 rtr_process_msg(struct rtr_session *rs)
984 {
985 	struct ibuf rbuf, hdr, msg;
986 	size_t msglen;
987 	enum rtr_pdu_type msgtype;
988 
989 	ibuf_from_buffer(&rbuf, rs->r.buf, rs->r.wpos);
990 
991 	for (;;) {
992 		if (ibuf_size(&rbuf) < sizeof(struct rtr_header))
993 			break;
994 
995 		/* parse header */
996 		ibuf_from_buffer(&hdr, ibuf_data(&rbuf),
997 		    sizeof(struct rtr_header));
998 		if (rtr_parse_header(rs, &hdr, &msglen, &msgtype) == -1)
999 			return;
1000 
1001 		/* extract message */
1002 		if (ibuf_get_ibuf(&rbuf, msglen, &msg) == -1)
1003 			break;
1004 
1005 		switch (msgtype) {
1006 		case SERIAL_NOTIFY:
1007 			if (rtr_parse_notify(rs, &msg) == -1)
1008 				return;
1009 			break;
1010 		case CACHE_RESPONSE:
1011 			if (rtr_parse_cache_response(rs, &msg) == -1)
1012 				return;
1013 			break;
1014 		case IPV4_PREFIX:
1015 			if (rtr_parse_ipv4_prefix(rs, &msg) == -1)
1016 				return;
1017 			break;
1018 		case IPV6_PREFIX:
1019 			if (rtr_parse_ipv6_prefix(rs, &msg) == -1)
1020 				return;
1021 			break;
1022 		case END_OF_DATA:
1023 			if (rtr_parse_end_of_data(rs, &msg) == -1)
1024 				return;
1025 			break;
1026 		case CACHE_RESET:
1027 			if (rtr_parse_cache_reset(rs, &msg) == -1)
1028 				return;
1029 			break;
1030 		case ROUTER_KEY:
1031 			/* silently ignore router key */
1032 			break;
1033 		case ERROR_REPORT:
1034 			if (rtr_parse_error(rs, &msg) == -1) {
1035 				/* no need to send back an error */
1036 				return;
1037 			}
1038 			break;
1039 		case ASPA:
1040 			if (rtr_parse_aspa(rs, &msg) == -1)
1041 				return;
1042 			break;
1043 		default:
1044 			/* unreachable, checked in rtr_parse_header() */
1045 			rtr_send_error(rs, &msg, UNSUPP_PDU_TYPE, "type %s",
1046 			    log_rtr_type(msgtype));
1047 			return;
1048 		}
1049 	}
1050 
1051 	memmove(&rs->r.buf, ibuf_data(&rbuf), ibuf_size(&rbuf));
1052 	rs->r.wpos = ibuf_size(&rbuf);
1053 }
1054 
1055 /*
1056  * Simple FSM for RTR sessions
1057  */
1058 static void
1059 rtr_fsm(struct rtr_session *rs, enum rtr_event event)
1060 {
1061 	enum rtr_state prev_state = rs->state;
1062 
1063 	switch (event) {
1064 	case RTR_EVNT_UNSUPP_PROTO_VERSION:
1065 		if (rs->state == RTR_STATE_NEGOTIATION) {
1066 			if (rs->version > 0)
1067 				rs->version--;
1068 			else {
1069 				/*
1070 				 * can't downgrade anymore, fail connection
1071 				 * RFC requires to send the error with our
1072 				 * highest version number.
1073 				 */
1074 				rs->version = RTR_MAX_VERSION;
1075 				rtr_send_error(rs, NULL, UNSUPP_PROTOCOL_VERS,
1076 				    "negotiation failed");
1077 				return;
1078 			}
1079 
1080 			if (rs->fd != -1) {
1081 				/* flush buffers */
1082 				msgbuf_clear(&rs->w);
1083 				rs->r.wpos = 0;
1084 				close(rs->fd);
1085 				rs->fd = -1;
1086 			}
1087 
1088 			/* retry connection with lower version */
1089 			timer_set(&rs->timers, Timer_Rtr_Retry, rs->retry);
1090 			rtr_imsg_compose(IMSG_SOCKET_CONN, rs->id, 0, NULL, 0);
1091 			break;
1092 		}
1093 		/* FALLTHROUGH */
1094 	case RTR_EVNT_RESET_AND_CLOSE:
1095 		rtr_reset_cache(rs);
1096 		rtr_recalc();
1097 		/* FALLTHROUGH */
1098 	case RTR_EVNT_CON_CLOSE:
1099 		if (rs->state == RTR_STATE_NEGOTIATION) {
1100 			/* consider any close event as a version failure. */
1101 			rtr_fsm(rs, RTR_EVNT_UNSUPP_PROTO_VERSION);
1102 			break;
1103 		}
1104 		if (rs->fd != -1) {
1105 			/* flush buffers */
1106 			msgbuf_clear(&rs->w);
1107 			rs->r.wpos = 0;
1108 			close(rs->fd);
1109 			rs->fd = -1;
1110 		}
1111 		rs->state = RTR_STATE_CLOSED;
1112 		/* try to reopen session */
1113 		timer_set(&rs->timers, Timer_Rtr_Retry,
1114 		    arc4random_uniform(10));
1115 		break;
1116 	case RTR_EVNT_START:
1117 	case RTR_EVNT_TIMER_RETRY:
1118 		switch (rs->state) {
1119 		case RTR_STATE_ERROR:
1120 			rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1121 			return;
1122 		case RTR_STATE_CLOSED:
1123 			timer_set(&rs->timers, Timer_Rtr_Retry, rs->retry);
1124 			rtr_imsg_compose(IMSG_SOCKET_CONN, rs->id, 0, NULL, 0);
1125 			return;
1126 		default:
1127 			break;
1128 		}
1129 		/* FALLTHROUGH */
1130 	case RTR_EVNT_CON_OPEN:
1131 		timer_stop(&rs->timers, Timer_Rtr_Retry);
1132 		if (rs->session_id == -1)
1133 			rtr_send_reset_query(rs);
1134 		else
1135 			rtr_send_serial_query(rs);
1136 		break;
1137 	case RTR_EVNT_SERIAL_NOTIFY:
1138 		/* schedule a refresh after a quick wait */
1139 		timer_set(&rs->timers, Timer_Rtr_Refresh,
1140 		    arc4random_uniform(10));
1141 		break;
1142 	case RTR_EVNT_TIMER_REFRESH:
1143 		/* send serial query */
1144 		rtr_send_serial_query(rs);
1145 		break;
1146 	case RTR_EVNT_TIMER_EXPIRE:
1147 		rtr_reset_cache(rs);
1148 		rtr_recalc();
1149 		break;
1150 	case RTR_EVNT_TIMER_ACTIVE:
1151 		log_warnx("rtr %s: activity timer fired", log_rtr(rs));
1152 		rtr_sem_release(rs->active_lock);
1153 		rtr_recalc();
1154 		rs->active_lock = 0;
1155 		break;
1156 	case RTR_EVNT_CACHE_RESPONSE:
1157 		rs->state = RTR_STATE_EXCHANGE;
1158 		timer_stop(&rs->timers, Timer_Rtr_Refresh);
1159 		timer_stop(&rs->timers, Timer_Rtr_Retry);
1160 		timer_set(&rs->timers, Timer_Rtr_Active, rs->active);
1161 		/* prevent rtr_recalc from running while active */
1162 		rs->active_lock = 1;
1163 		rtr_sem_acquire(rs->active_lock);
1164 		break;
1165 	case RTR_EVNT_END_OF_DATA:
1166 		/* start refresh and expire timers */
1167 		timer_set(&rs->timers, Timer_Rtr_Refresh, rs->refresh);
1168 		timer_set(&rs->timers, Timer_Rtr_Expire, rs->expire);
1169 		timer_stop(&rs->timers, Timer_Rtr_Active);
1170 		rs->state = RTR_STATE_ESTABLISHED;
1171 		rtr_sem_release(rs->active_lock);
1172 		rtr_recalc();
1173 		rs->active_lock = 0;
1174 		break;
1175 	case RTR_EVNT_CACHE_RESET:
1176 		rtr_reset_cache(rs);
1177 		rtr_recalc();
1178 		/* retry after a quick wait */
1179 		timer_set(&rs->timers, Timer_Rtr_Retry,
1180 		    arc4random_uniform(10));
1181 		break;
1182 	case RTR_EVNT_NO_DATA:
1183 		/* start retry timer */
1184 		timer_set(&rs->timers, Timer_Rtr_Retry, rs->retry);
1185 		/* stop refresh timer just to be sure */
1186 		timer_stop(&rs->timers, Timer_Rtr_Refresh);
1187 		rs->state = RTR_STATE_ESTABLISHED;
1188 		break;
1189 	case RTR_EVNT_SEND_ERROR:
1190 		rtr_reset_cache(rs);
1191 		rtr_recalc();
1192 		rs->state = RTR_STATE_ERROR;
1193 		/* flush receive buffer */
1194 		rs->r.wpos = 0;
1195 		break;
1196 	case RTR_EVNT_NEGOTIATION_DONE:
1197 		rs->state = RTR_STATE_ESTABLISHED;
1198 		break;
1199 	}
1200 
1201 	log_debug("rtr %s: state change %s -> %s, reason: %s",
1202 	    log_rtr(rs), rtr_statenames[prev_state], rtr_statenames[rs->state],
1203 	    rtr_eventnames[event]);
1204 }
1205 
1206 /*
1207  * IO handler for RTR sessions
1208  */
1209 static void
1210 rtr_dispatch_msg(struct pollfd *pfd, struct rtr_session *rs)
1211 {
1212 	ssize_t n;
1213 	int error;
1214 
1215 	if (pfd->revents & POLLHUP) {
1216 		log_warnx("rtr %s: Connection closed, hangup", log_rtr(rs));
1217 		rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1218 		return;
1219 	}
1220 	if (pfd->revents & (POLLERR|POLLNVAL)) {
1221 		log_warnx("rtr %s: Connection closed, error", log_rtr(rs));
1222 		rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1223 		return;
1224 	}
1225 	if (pfd->revents & POLLOUT && rs->w.queued) {
1226 		if ((error = ibuf_write(&rs->w)) == -1) {
1227 			if (errno != EAGAIN) {
1228 				log_warn("rtr %s: write error", log_rtr(rs));
1229 				rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1230 			}
1231 		}
1232 		if (error == 0)
1233 			rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1234 		if (rs->w.queued == 0 && rs->state == RTR_STATE_ERROR)
1235 			rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1236 	}
1237 	if (pfd->revents & POLLIN) {
1238 		if ((n = read(rs->fd, rs->r.buf + rs->r.wpos,
1239 		    sizeof(rs->r.buf) - rs->r.wpos)) == -1) {
1240 			if (errno != EINTR && errno != EAGAIN) {
1241 				log_warn("rtr %s: read error", log_rtr(rs));
1242 				rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1243 			}
1244 			return;
1245 		}
1246 		if (n == 0) {
1247 			rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1248 			return;
1249 		}
1250 		rs->r.wpos += n;
1251 
1252 		/* new data arrived, try to process it */
1253 		rtr_process_msg(rs);
1254 	}
1255 
1256 }
1257 
1258 void
1259 rtr_check_events(struct pollfd *pfds, size_t npfds)
1260 {
1261 	struct rtr_session *rs;
1262 	struct timer *t;
1263 	time_t now;
1264 	size_t i = 0;
1265 
1266 	for (i = 0; i < npfds; i++) {
1267 		if (pfds[i].revents == 0)
1268 			continue;
1269 		TAILQ_FOREACH(rs, &rtrs, entry)
1270 			if (rs->fd == pfds[i].fd) {
1271 				rtr_dispatch_msg(&pfds[i], rs);
1272 				break;
1273 			}
1274 		if (rs == NULL)
1275 			log_warnx("%s: unknown fd in pollfds", __func__);
1276 	}
1277 
1278 	/* run all timers */
1279 	now = getmonotime();
1280 	TAILQ_FOREACH(rs, &rtrs, entry)
1281 		if ((t = timer_nextisdue(&rs->timers, now)) != NULL) {
1282 			log_debug("rtr %s: %s triggered", log_rtr(rs),
1283 			    timernames[t->type]);
1284 			/* stop timer so it does not trigger again */
1285 			timer_stop(&rs->timers, t->type);
1286 			switch (t->type) {
1287 			case Timer_Rtr_Refresh:
1288 				rtr_fsm(rs, RTR_EVNT_TIMER_REFRESH);
1289 				break;
1290 			case Timer_Rtr_Retry:
1291 				rtr_fsm(rs, RTR_EVNT_TIMER_RETRY);
1292 				break;
1293 			case Timer_Rtr_Expire:
1294 				rtr_fsm(rs, RTR_EVNT_TIMER_EXPIRE);
1295 				break;
1296 			case Timer_Rtr_Active:
1297 				rtr_fsm(rs, RTR_EVNT_TIMER_ACTIVE);
1298 				break;
1299 			default:
1300 				fatalx("King Bula lost in time");
1301 			}
1302 		}
1303 }
1304 
1305 size_t
1306 rtr_count(void)
1307 {
1308 	struct rtr_session *rs;
1309 	size_t count = 0;
1310 
1311 	TAILQ_FOREACH(rs, &rtrs, entry)
1312 		count++;
1313 	return count;
1314 }
1315 
1316 size_t
1317 rtr_poll_events(struct pollfd *pfds, size_t npfds, time_t *timeout)
1318 {
1319 	struct rtr_session *rs;
1320 	time_t now = getmonotime();
1321 	size_t i = 0;
1322 
1323 	TAILQ_FOREACH(rs, &rtrs, entry) {
1324 		time_t nextaction;
1325 		struct pollfd *pfd = pfds + i++;
1326 
1327 		if (i > npfds)
1328 			fatalx("%s: too many sessions for pollfd", __func__);
1329 
1330 		if ((nextaction = timer_nextduein(&rs->timers, now)) != -1 &&
1331 		    nextaction < *timeout)
1332 			*timeout = nextaction;
1333 
1334 		if (rs->state == RTR_STATE_CLOSED) {
1335 			pfd->fd = -1;
1336 			continue;
1337 		}
1338 
1339 		pfd->fd = rs->fd;
1340 		pfd->events = 0;
1341 
1342 		if (rs->w.queued)
1343 			pfd->events |= POLLOUT;
1344 		if (rs->state >= RTR_STATE_ESTABLISHED)
1345 			pfd->events |= POLLIN;
1346 	}
1347 
1348 	return i;
1349 }
1350 
1351 struct rtr_session *
1352 rtr_new(uint32_t id, char *descr)
1353 {
1354 	struct rtr_session *rs;
1355 
1356 	if ((rs = calloc(1, sizeof(*rs))) == NULL)
1357 		fatal("RTR session %s", descr);
1358 
1359 	RB_INIT(&rs->roa_set);
1360 	RB_INIT(&rs->aspa);
1361 	RB_INIT(&rs->aspa_oldv6);
1362 	TAILQ_INIT(&rs->timers);
1363 	msgbuf_init(&rs->w);
1364 
1365 	strlcpy(rs->descr, descr, sizeof(rs->descr));
1366 	rs->id = id;
1367 	rs->session_id = -1;
1368 	rs->version = RTR_MAX_VERSION;
1369 	rs->refresh = RTR_DEFAULT_REFRESH;
1370 	rs->retry = RTR_DEFAULT_RETRY;
1371 	rs->expire = RTR_DEFAULT_EXPIRE;
1372 	rs->active = RTR_DEFAULT_ACTIVE;
1373 	rs->state = RTR_STATE_CLOSED;
1374 	rs->reconf_action = RECONF_REINIT;
1375 	rs->last_recv_error = NO_ERROR;
1376 	rs->last_sent_error = NO_ERROR;
1377 
1378 	/* make sure that some timer is running to abort bad sessions */
1379 	timer_set(&rs->timers, Timer_Rtr_Expire, rs->expire);
1380 
1381 	log_debug("rtr %s: new session, start", log_rtr(rs));
1382 	TAILQ_INSERT_TAIL(&rtrs, rs, entry);
1383 	rtr_fsm(rs, RTR_EVNT_START);
1384 
1385 	return rs;
1386 }
1387 
1388 struct rtr_session *
1389 rtr_get(uint32_t id)
1390 {
1391 	struct rtr_session *rs;
1392 
1393 	TAILQ_FOREACH(rs, &rtrs, entry)
1394 		if (rs->id == id)
1395 			return rs;
1396 	return NULL;
1397 }
1398 
1399 void
1400 rtr_free(struct rtr_session *rs)
1401 {
1402 	if (rs == NULL)
1403 		return;
1404 
1405 	rtr_reset_cache(rs);
1406 	rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1407 	timer_remove_all(&rs->timers);
1408 	free(rs);
1409 }
1410 
1411 void
1412 rtr_open(struct rtr_session *rs, int fd)
1413 {
1414 	if (rs->state != RTR_STATE_CLOSED &&
1415 	    rs->state != RTR_STATE_NEGOTIATION) {
1416 		log_warnx("rtr %s: bad session state", log_rtr(rs));
1417 		rtr_fsm(rs, RTR_EVNT_CON_CLOSE);
1418 	}
1419 
1420 	if (rs->state == RTR_STATE_CLOSED)
1421 		rs->version = RTR_MAX_VERSION;
1422 
1423 	rs->fd = rs->w.fd = fd;
1424 	rs->state = RTR_STATE_NEGOTIATION;
1425 	rtr_fsm(rs, RTR_EVNT_CON_OPEN);
1426 }
1427 
1428 void
1429 rtr_config_prep(void)
1430 {
1431 	struct rtr_session *rs;
1432 
1433 	TAILQ_FOREACH(rs, &rtrs, entry)
1434 		rs->reconf_action = RECONF_DELETE;
1435 }
1436 
1437 void
1438 rtr_config_merge(void)
1439 {
1440 	struct rtr_session *rs, *nrs;
1441 
1442 	TAILQ_FOREACH_SAFE(rs, &rtrs, entry, nrs)
1443 		if (rs->reconf_action == RECONF_DELETE) {
1444 			TAILQ_REMOVE(&rtrs, rs, entry);
1445 			rtr_free(rs);
1446 		}
1447 }
1448 
1449 void
1450 rtr_config_keep(struct rtr_session *rs)
1451 {
1452 	rs->reconf_action = RECONF_KEEP;
1453 }
1454 
1455 void
1456 rtr_roa_merge(struct roa_tree *rt)
1457 {
1458 	struct rtr_session *rs;
1459 	struct roa *roa;
1460 
1461 	TAILQ_FOREACH(rs, &rtrs, entry) {
1462 		RB_FOREACH(roa, roa_tree, &rs->roa_set)
1463 			rtr_roa_insert(rt, roa);
1464 	}
1465 }
1466 
1467 void
1468 rtr_aspa_merge(struct aspa_tree *at)
1469 {
1470 	struct rtr_session *rs;
1471 	struct aspa_set *aspa;
1472 
1473 	TAILQ_FOREACH(rs, &rtrs, entry) {
1474 		RB_FOREACH(aspa, aspa_tree, &rs->aspa)
1475 			rtr_aspa_insert(at, aspa);
1476 		RB_FOREACH(aspa, aspa_tree, &rs->aspa_oldv6)
1477 			rtr_aspa_insert(at, aspa);
1478 	}
1479 }
1480 
1481 void
1482 rtr_shutdown(void)
1483 {
1484 	struct rtr_session *rs, *nrs;
1485 
1486 	TAILQ_FOREACH_SAFE(rs, &rtrs, entry, nrs)
1487 		rtr_free(rs);
1488 }
1489 
1490 void
1491 rtr_show(struct rtr_session *rs, pid_t pid)
1492 {
1493 	struct ctl_show_rtr msg;
1494 	struct ctl_timer ct;
1495 	u_int i;
1496 	time_t d;
1497 
1498 	memset(&msg, 0, sizeof(msg));
1499 
1500 	/* descr, remote_addr, local_addr and remote_port set by parent */
1501 	msg.version = rs->version;
1502 	msg.serial = rs->serial;
1503 	msg.refresh = rs->refresh;
1504 	msg.retry = rs->retry;
1505 	msg.expire = rs->expire;
1506 	msg.session_id = rs->session_id;
1507 	msg.last_sent_error = rs->last_sent_error;
1508 	msg.last_recv_error = rs->last_recv_error;
1509 	strlcpy(msg.last_sent_msg, rs->last_sent_msg,
1510 	    sizeof(msg.last_sent_msg));
1511 	strlcpy(msg.last_recv_msg, rs->last_recv_msg,
1512 	    sizeof(msg.last_recv_msg));
1513 
1514 	/* send back imsg */
1515 	rtr_imsg_compose(IMSG_CTL_SHOW_RTR, rs->id, pid, &msg, sizeof(msg));
1516 
1517 	/* send back timer imsgs */
1518 	for (i = 1; i < Timer_Max; i++) {
1519 		if (!timer_running(&rs->timers, i, &d))
1520 			continue;
1521 		ct.type = i;
1522 		ct.val = d;
1523 		rtr_imsg_compose(IMSG_CTL_SHOW_TIMER, rs->id, pid,
1524 		    &ct, sizeof(ct));
1525 	}
1526 }
1527