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