]> git.ipfire.org Git - thirdparty/bird.git/blob - proto/rpki/rpki.c
RPKI: retry timer doesn't reset connections when more data is pending
[thirdparty/bird.git] / proto / rpki / rpki.c
1 /*
2 * BIRD -- The Resource Public Key Infrastructure (RPKI) to Router Protocol
3 *
4 * (c) 2015 CZ.NIC
5 * (c) 2015 Pavel Tvrdik <pawel.tvrdik@gmail.com>
6 *
7 * Using RTRlib: http://rpki.realmv6.org/
8 *
9 * Can be freely distributed and used under the terms of the GNU GPL.
10 */
11
12 /**
13 * DOC: RPKI To Router (RPKI-RTR)
14 *
15 * The RPKI-RTR protocol is implemented in several files: |rpki.c| containing
16 * the routes handling, protocol logic, timer events, cache connection,
17 * reconfiguration, configuration and protocol glue with BIRD core, |packets.c|
18 * containing the RPKI packets handling and finally all transports files:
19 * |transport.c|, |tcp_transport.c| and |ssh_transport.c|.
20 *
21 * The |transport.c| is a middle layer and interface for each specific
22 * transport. Transport is a way how to wrap a communication with a cache
23 * server. There is supported an unprotected TCP transport and an encrypted
24 * SSHv2 transport. The SSH transport requires LibSSH library. LibSSH is
25 * loading dynamically using |dlopen()| function. SSH support is integrated in
26 * |sysdep/unix/io.c|. Each transport must implement an initialization
27 * function, an open function and a socket identification function. That's all.
28 *
29 * This implementation is based on the RTRlib (http://rpki.realmv6.org/). The
30 * BIRD takes over files |packets.c|, |rtr.c| (inside |rpki.c|), |transport.c|,
31 * |tcp_transport.c| and |ssh_transport.c| from RTRlib.
32 *
33 * A RPKI-RTR connection is described by a structure &rpki_cache. The main
34 * logic is located in |rpki_cache_change_state()| function. There is a state
35 * machine. The standard starting state flow looks like |Down| ~> |Connecting|
36 * ~> |Sync-Start| ~> |Sync-Running| ~> |Established| and then the last three
37 * states are periodically repeated.
38 *
39 * |Connecting| state establishes the transport connection. The state from a
40 * call |rpki_cache_change_state(CONNECTING)| to a call |rpki_connected_hook()|
41 *
42 * |Sync-Start| state starts with sending |Reset Query| or |Serial Query| and
43 * then waits for |Cache Response|. The state from |rpki_connected_hook()| to
44 * |rpki_handle_cache_response_pdu()|
45 *
46 * During |Sync-Running| BIRD receives data with IPv4/IPv6 Prefixes from cache
47 * server. The state starts from |rpki_handle_cache_response_pdu()| and ends
48 * in |rpki_handle_end_of_data_pdu()|.
49 *
50 * |Established| state means that BIRD has synced all data with cache server.
51 * Schedules a refresh timer event that invokes |Sync-Start|. Schedules Expire
52 * timer event and stops a Retry timer event.
53 *
54 * |Transport Error| state means that we have some troubles with a network
55 * connection. We cannot connect to a cache server or we wait too long for some
56 * expected PDU for received - |Cache Response| or |End of Data|. It closes
57 * current connection and schedules a Retry timer event.
58 *
59 * |Fatal Protocol Error| is occurred e.g. by received a bad Session ID. We
60 * restart a protocol, so all ROAs are flushed immediately.
61 *
62 * The RPKI-RTR protocol (RFC 6810 bis) defines configurable refresh, retry and
63 * expire intervals. For maintaining a connection are used timer events that
64 * are scheduled by |rpki_schedule_next_refresh()|,
65 * |rpki_schedule_next_retry()| and |rpki_schedule_next_expire()| functions.
66 *
67 * A Refresh timer event performs a sync of |Established| connection. So it
68 * shifts state to |Sync-Start|. If at the beginning of second call of a
69 * refresh event is connection in |Sync-Start| state then we didn't receive a
70 * |Cache Response| from a cache server and we invoke |Transport Error| state.
71 *
72 * A Retry timer event attempts to connect cache server. It is activated after
73 * |Transport Error| state and terminated by reaching |Established| state.
74 * If cache connection is still connecting to the cache server at the beginning
75 * of an event call then the Retry timer event invokes |Transport Error| state.
76 *
77 * An Expire timer event checks expiration of ROAs. If a last successful sync
78 * was more ago than the expire interval then the Expire timer event invokes a
79 * protocol restart thereby removes all ROAs learned from that cache server and
80 * continue trying to connect to cache server. The Expire event is activated
81 * by initial successful loading of ROAs, receiving End of Data PDU.
82 *
83 * A reconfiguration of cache connection works well without restarting when we
84 * change only intervals values.
85 *
86 * Supported standards:
87 * - RFC 6810 - main RPKI-RTR standard
88 * - RFC 6810 bis - an explicit timing parameters and protocol version number negotiation
89 */
90
91 #include <stdlib.h>
92 #include <netdb.h>
93
94 #undef LOCAL_DEBUG
95
96 #include "rpki.h"
97 #include "lib/string.h"
98 #include "nest/cli.h"
99
100 /* Return values for reconfiguration functions */
101 #define NEED_RESTART 0
102 #define SUCCESSFUL_RECONF 1
103
104 static int rpki_open_connection(struct rpki_cache *cache);
105 static void rpki_close_connection(struct rpki_cache *cache);
106 static void rpki_schedule_next_refresh(struct rpki_cache *cache);
107 static void rpki_schedule_next_retry(struct rpki_cache *cache);
108 static void rpki_schedule_next_expire_check(struct rpki_cache *cache);
109 static void rpki_stop_refresh_timer_event(struct rpki_cache *cache);
110 static void rpki_stop_retry_timer_event(struct rpki_cache *cache);
111 static void rpki_stop_expire_timer_event(struct rpki_cache *cache);
112
113
114 /*
115 * Routes handling
116 */
117
118 void
119 rpki_table_add_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr)
120 {
121 struct rpki_proto *p = cache->p;
122
123 rta a0 = {
124 .pref = channel->preference,
125 .source = RTS_RPKI,
126 .scope = SCOPE_UNIVERSE,
127 .dest = RTD_NONE,
128 };
129
130 rta *a = rta_lookup(&a0);
131 rte *e = rte_get_temp(a, p->p.main_source);
132
133 rte_update2(channel, &pfxr->n, e, e->src);
134 }
135
136 void
137 rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr)
138 {
139 struct rpki_proto *p = cache->p;
140 rte_update2(channel, &pfxr->n, NULL, p->p.main_source);
141 }
142
143
144 /*
145 * RPKI Protocol Logic
146 */
147
148 static const char *str_cache_states[] = {
149 [RPKI_CS_CONNECTING] = "Connecting",
150 [RPKI_CS_ESTABLISHED] = "Established",
151 [RPKI_CS_RESET] = "Reseting",
152 [RPKI_CS_SYNC_START] = "Sync-Start",
153 [RPKI_CS_SYNC_RUNNING] = "Sync-Running",
154 [RPKI_CS_FAST_RECONNECT] = "Fast-Reconnect",
155 [RPKI_CS_NO_INCR_UPDATE_AVAIL]= "No-Increment-Update-Available",
156 [RPKI_CS_ERROR_NO_DATA_AVAIL] = "Cache-Error-No-Data-Available",
157 [RPKI_CS_ERROR_FATAL] = "Fatal-Protocol-Error",
158 [RPKI_CS_ERROR_TRANSPORT] = "Transport-Error",
159 [RPKI_CS_SHUTDOWN] = "Down"
160 };
161
162 /**
163 * rpki_cache_state_to_str - give a text representation of cache state
164 * @state: A cache state
165 *
166 * The function converts logic cache state into string.
167 */
168 const char *
169 rpki_cache_state_to_str(enum rpki_cache_state state)
170 {
171 return str_cache_states[state];
172 }
173
174 /**
175 * rpki_start_cache - connect to a cache server
176 * @cache: RPKI connection instance
177 *
178 * This function is a high level method to kick up a connection to a cache server.
179 */
180 static void
181 rpki_start_cache(struct rpki_cache *cache)
182 {
183 rpki_cache_change_state(cache, RPKI_CS_CONNECTING);
184 }
185
186 /**
187 * rpki_force_restart_proto - force shutdown and start protocol again
188 * @p: RPKI protocol instance
189 *
190 * This function calls shutdown and frees all protocol resources as well.
191 * After calling this function should be no operations with protocol data,
192 * they could be freed already.
193 */
194 static void
195 rpki_force_restart_proto(struct rpki_proto *p)
196 {
197 if (p->cache)
198 {
199 CACHE_DBG(p->cache, "Connection object destroying");
200 }
201
202 /* Sign as freed */
203 p->cache = NULL;
204
205 proto_notify_state(&p->p, PS_DOWN);
206 }
207
208 /**
209 * rpki_cache_change_state - check and change cache state
210 * @cache: RPKI cache instance
211 * @new_state: suggested new state
212 *
213 * This function makes transitions between internal states.
214 * It represents the core of logic management of RPKI protocol.
215 * Cannot transit into the same state as cache is in already.
216 */
217 void
218 rpki_cache_change_state(struct rpki_cache *cache, const enum rpki_cache_state new_state)
219 {
220 const enum rpki_cache_state old_state = cache->state;
221
222 if (old_state == new_state)
223 return;
224
225 cache->state = new_state;
226 CACHE_TRACE(D_EVENTS, cache, "Changing from %s to %s state", rpki_cache_state_to_str(old_state), rpki_cache_state_to_str(new_state));
227
228 switch (new_state)
229 {
230 case RPKI_CS_CONNECTING:
231 {
232 sock *sk = cache->tr_sock->sk;
233
234 if (sk == NULL || sk->fd < 0)
235 rpki_open_connection(cache);
236 else
237 rpki_cache_change_state(cache, RPKI_CS_SYNC_START);
238
239 rpki_schedule_next_retry(cache);
240 break;
241 }
242
243 case RPKI_CS_ESTABLISHED:
244 rpki_schedule_next_refresh(cache);
245 rpki_schedule_next_expire_check(cache);
246 rpki_stop_retry_timer_event(cache);
247 break;
248
249 case RPKI_CS_RESET:
250 /* Resetting cache connection. */
251 cache->request_session_id = 1;
252 cache->serial_num = 0;
253 rpki_cache_change_state(cache, RPKI_CS_SYNC_START);
254 break;
255
256 case RPKI_CS_SYNC_START:
257 /* Requesting for receive ROAs from a cache server. */
258 if (cache->request_session_id)
259 {
260 /* Send request for Session ID */
261 if (rpki_send_reset_query(cache) != RPKI_SUCCESS)
262 rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
263 }
264 else
265 {
266 /* We have already a session_id. So send a Serial Query and start an incremental sync */
267 if (rpki_send_serial_query(cache) != RPKI_SUCCESS)
268 rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
269 }
270 break;
271
272 case RPKI_CS_SYNC_RUNNING:
273 /* The state between Cache Response and End of Data. Only waiting for
274 * receiving all IP Prefix PDUs and finally a End of Data PDU. */
275 break;
276
277 case RPKI_CS_NO_INCR_UPDATE_AVAIL:
278 /* Server was unable to answer the last Serial Query and sent Cache Reset. */
279 case RPKI_CS_ERROR_NO_DATA_AVAIL:
280 /* No validation records are available on the cache server. */
281
282 if (old_state == RPKI_CS_ESTABLISHED)
283 rpki_cache_change_state(cache, RPKI_CS_RESET);
284 else
285 rpki_schedule_next_retry(cache);
286 break;
287
288 case RPKI_CS_ERROR_FATAL:
289 /* Fatal protocol error occurred. */
290 rpki_force_restart_proto(cache->p);
291 break;
292
293 case RPKI_CS_ERROR_TRANSPORT:
294 /* Error on the transport socket occurred. */
295 rpki_close_connection(cache);
296 rpki_schedule_next_retry(cache);
297 rpki_stop_refresh_timer_event(cache);
298 cache->request_session_id = 1;
299 break;
300
301 case RPKI_CS_FAST_RECONNECT:
302 /* Reconnect without any waiting period */
303 rpki_close_connection(cache);
304 rpki_cache_change_state(cache, RPKI_CS_CONNECTING);
305 break;
306
307 case RPKI_CS_SHUTDOWN:
308 bug("This isn't never really called.");
309 break;
310 };
311 }
312
313
314 /*
315 * RPKI Timer Events
316 */
317
318 static void
319 rpki_schedule_next_refresh(struct rpki_cache *cache)
320 {
321 btime t = cache->refresh_interval S;
322
323 CACHE_DBG(cache, "after %t s", t);
324 tm_start(cache->refresh_timer, t);
325 }
326
327 static void
328 rpki_schedule_next_retry(struct rpki_cache *cache)
329 {
330 btime t = cache->retry_interval S;
331
332 CACHE_DBG(cache, "after %t s", t);
333 tm_start(cache->retry_timer, t);
334 }
335
336 static void
337 rpki_schedule_next_expire_check(struct rpki_cache *cache)
338 {
339 /* A minimum time to wait is 1 second */
340 btime t = cache->last_update + cache->expire_interval S - current_time();
341 t = MAX(t, 1 S);
342
343 CACHE_DBG(cache, "after %t s", t);
344 tm_start(cache->expire_timer, t);
345 }
346
347 static void
348 rpki_stop_refresh_timer_event(struct rpki_cache *cache)
349 {
350 CACHE_DBG(cache, "Stop");
351 tm_stop(cache->refresh_timer);
352 }
353
354 static void
355 rpki_stop_retry_timer_event(struct rpki_cache *cache)
356 {
357 CACHE_DBG(cache, "Stop");
358 tm_stop(cache->retry_timer);
359 }
360
361 static void UNUSED
362 rpki_stop_expire_timer_event(struct rpki_cache *cache)
363 {
364 CACHE_DBG(cache, "Stop");
365 tm_stop(cache->expire_timer);
366 }
367
368 static int
369 rpki_sync_is_stuck(struct rpki_cache *cache)
370 {
371 return !sk_rx_ready(cache->tr_sock->sk) && (
372 !cache->last_rx_prefix || (current_time() - cache->last_rx_prefix > 10 S)
373 );
374 }
375
376 /**
377 * rpki_refresh_hook - control a scheduling of downloading data from cache server
378 * @tm: refresh timer with cache connection instance in data
379 *
380 * This function is periodically called during &ESTABLISHED or &SYNC* state
381 * cache connection. The first refresh schedule is invoked after receiving a
382 * |End of Data| PDU and has run by some &ERROR is occurred.
383 */
384 static void
385 rpki_refresh_hook(timer *tm)
386 {
387 struct rpki_cache *cache = tm->data;
388
389 CACHE_DBG(cache, "%s", rpki_cache_state_to_str(cache->state));
390
391 switch (cache->state)
392 {
393 case RPKI_CS_ESTABLISHED:
394 rpki_cache_change_state(cache, RPKI_CS_SYNC_START);
395 break;
396
397 case RPKI_CS_SYNC_START:
398 /* We sent Serial/Reset Query in last refresh hook call
399 * and didn't receive Cache Response yet. It is probably
400 * troubles with network. */
401 case RPKI_CS_SYNC_RUNNING:
402 /* We sent Serial/Reset Query in last refresh hook call
403 * and we got Cache Response but didn't get End-Of-Data yet.
404 * It could be a trouble with network or only too long synchronization. */
405 if (rpki_sync_is_stuck(cache))
406 {
407 CACHE_TRACE(D_EVENTS, cache, "Sync takes more time than refresh interval %us, resetting connection", cache->refresh_interval);
408 rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
409 }
410 break;
411
412 default:
413 break;
414 }
415
416 if (cache->state != RPKI_CS_SHUTDOWN && cache->state != RPKI_CS_ERROR_TRANSPORT)
417 rpki_schedule_next_refresh(cache);
418 else
419 rpki_stop_refresh_timer_event(cache);
420 }
421
422 /**
423 * rpki_retry_hook - control a scheduling of retrying connection to cache server
424 * @tm: retry timer with cache connection instance in data
425 *
426 * This function is periodically called during &ERROR* state cache connection.
427 * The first retry schedule is invoked after any &ERROR* state occurred and
428 * ends by reaching of &ESTABLISHED state again.
429 */
430 static void
431 rpki_retry_hook(timer *tm)
432 {
433 struct rpki_cache *cache = tm->data;
434
435 CACHE_DBG(cache, "%s", rpki_cache_state_to_str(cache->state));
436
437 switch (cache->state)
438 {
439 case RPKI_CS_ESTABLISHED:
440 case RPKI_CS_SHUTDOWN:
441 break;
442
443 case RPKI_CS_CONNECTING:
444 case RPKI_CS_SYNC_START:
445 case RPKI_CS_SYNC_RUNNING:
446 if (rpki_sync_is_stuck(cache))
447 {
448 /* We tried to establish a connection in last retry hook call and haven't done
449 * yet. It looks like troubles with network. We are aggressive here. */
450 CACHE_TRACE(D_EVENTS, cache, "Sync takes more time than retry interval %us, resetting connection.", cache->retry_interval);
451 rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
452 }
453 break;
454
455 case RPKI_CS_NO_INCR_UPDATE_AVAIL:
456 case RPKI_CS_ERROR_NO_DATA_AVAIL:
457 rpki_cache_change_state(cache, RPKI_CS_RESET);
458 break;
459
460 default:
461 rpki_cache_change_state(cache, RPKI_CS_CONNECTING);
462 break;
463 }
464
465 if (cache->state != RPKI_CS_ESTABLISHED)
466 rpki_schedule_next_retry(cache);
467 else
468 rpki_stop_retry_timer_event(cache);
469 }
470
471 /**
472 * rpki_expire_hook - control a expiration of ROA entries
473 * @tm: expire timer with cache connection instance in data
474 *
475 * This function is scheduled after received a |End of Data| PDU.
476 * A waiting interval is calculated dynamically by last update.
477 * If we reach an expiration time then we invoke a restarting
478 * of the protocol.
479 */
480 static void
481 rpki_expire_hook(timer *tm)
482 {
483 struct rpki_cache *cache = tm->data;
484
485 if (!cache->last_update)
486 return;
487
488 CACHE_DBG(cache, "%s", rpki_cache_state_to_str(cache->state));
489
490 btime t = cache->last_update + cache->expire_interval S - current_time();
491 if (t <= 0)
492 {
493 CACHE_TRACE(D_EVENTS, cache, "All ROAs expired");
494 rpki_force_restart_proto(cache->p);
495 }
496 else
497 {
498 CACHE_DBG(cache, "Remains %t seconds to become ROAs obsolete", t);
499 rpki_schedule_next_expire_check(cache);
500 }
501 }
502
503 /**
504 * rpki_check_refresh_interval - check validity of refresh interval value
505 * @seconds: suggested value
506 *
507 * This function validates value and should return |NULL|.
508 * If the check doesn't pass then returns error message.
509 */
510 const char *
511 rpki_check_refresh_interval(uint seconds)
512 {
513 if (seconds < 1)
514 return "Minimum allowed refresh interval is 1 second";
515 if (seconds > 86400)
516 return "Maximum allowed refresh interval is 86400 seconds";
517 return NULL;
518 }
519
520 /**
521 * rpki_check_retry_interval - check validity of retry interval value
522 * @seconds: suggested value
523 *
524 * This function validates value and should return |NULL|.
525 * If the check doesn't pass then returns error message.
526 */
527 const char *
528 rpki_check_retry_interval(uint seconds)
529 {
530 if (seconds < 1)
531 return "Minimum allowed retry interval is 1 second";
532 if (seconds > 7200)
533 return "Maximum allowed retry interval is 7200 seconds";
534 return NULL;
535 }
536
537 /**
538 * rpki_check_expire_interval - check validity of expire interval value
539 * @seconds: suggested value
540 *
541 * This function validates value and should return |NULL|.
542 * If the check doesn't pass then returns error message.
543 */
544 const char *
545 rpki_check_expire_interval(uint seconds)
546 {
547 if (seconds < 600)
548 return "Minimum allowed expire interval is 600 seconds";
549 if (seconds > 172800)
550 return "Maximum allowed expire interval is 172800 seconds";
551 return NULL;
552 }
553
554
555 /*
556 * RPKI Cache
557 */
558
559 static struct rpki_cache *
560 rpki_init_cache(struct rpki_proto *p, struct rpki_config *cf)
561 {
562 pool *pool = rp_new(p->p.pool, cf->hostname);
563
564 struct rpki_cache *cache = mb_allocz(pool, sizeof(struct rpki_cache));
565
566 cache->pool = pool;
567 cache->p = p;
568
569 cache->state = RPKI_CS_SHUTDOWN;
570 cache->request_session_id = 1;
571 cache->version = RPKI_MAX_VERSION;
572
573 cache->refresh_interval = cf->refresh_interval;
574 cache->retry_interval = cf->retry_interval;
575 cache->expire_interval = cf->expire_interval;
576 cache->refresh_timer = tm_new_init(pool, &rpki_refresh_hook, cache, 0, 0);
577 cache->retry_timer = tm_new_init(pool, &rpki_retry_hook, cache, 0, 0);
578 cache->expire_timer = tm_new_init(pool, &rpki_expire_hook, cache, 0, 0);
579
580 cache->tr_sock = mb_allocz(pool, sizeof(struct rpki_tr_sock));
581 cache->tr_sock->cache = cache;
582
583 switch (cf->tr_config.type)
584 {
585 case RPKI_TR_TCP: rpki_tr_tcp_init(cache->tr_sock); break;
586 #if HAVE_LIBSSH
587 case RPKI_TR_SSH: rpki_tr_ssh_init(cache->tr_sock); break;
588 #endif
589 };
590
591 CACHE_DBG(cache, "Connection object created");
592
593 return cache;
594 }
595
596 /**
597 * rpki_get_cache_ident - give a text representation of cache server name
598 * @cache: RPKI connection instance
599 *
600 * The function converts cache connection into string.
601 */
602 const char *
603 rpki_get_cache_ident(struct rpki_cache *cache)
604 {
605 return rpki_tr_ident(cache->tr_sock);
606 }
607
608 static int
609 rpki_open_connection(struct rpki_cache *cache)
610 {
611 CACHE_TRACE(D_EVENTS, cache, "Opening a connection");
612
613 if (rpki_tr_open(cache->tr_sock) == RPKI_TR_ERROR)
614 {
615 rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
616 return RPKI_TR_ERROR;
617 }
618
619 return RPKI_TR_SUCCESS;
620 }
621
622 static void
623 rpki_close_connection(struct rpki_cache *cache)
624 {
625 CACHE_TRACE(D_EVENTS, cache, "Closing a connection");
626 rpki_tr_close(cache->tr_sock);
627 proto_notify_state(&cache->p->p, PS_START);
628 }
629
630 static int
631 rpki_shutdown(struct proto *P)
632 {
633 struct rpki_proto *p = (void *) P;
634
635 rpki_force_restart_proto(p);
636
637 /* Protocol memory pool will be automatically freed */
638 return PS_DOWN;
639 }
640
641
642 /*
643 * RPKI Reconfiguration
644 */
645
646 /**
647 * rpki_reconfigure_cache - a cache reconfiguration
648 * @p: RPKI protocol instance
649 * @cache: a cache connection
650 * @new: new RPKI configuration
651 * @old: old RPKI configuration
652 *
653 * This function reconfigures existing single cache server connection with new
654 * existing configuration. Generally, a change of time intervals could be
655 * reconfigured without restarting and all others changes requires a restart of
656 * protocol. Returns |NEED_TO_RESTART| or |SUCCESSFUL_RECONF|.
657 */
658 static int
659 rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, struct rpki_config *new, struct rpki_config *old)
660 {
661 u8 try_reset = 0;
662 u8 try_fast_reconnect = 0;
663
664 if (strcmp(old->hostname, new->hostname) != 0)
665 {
666 CACHE_TRACE(D_EVENTS, cache, "Cache server address changed to %s", new->hostname);
667 return NEED_RESTART;
668 }
669
670 if (old->port != new->port)
671 {
672 CACHE_TRACE(D_EVENTS, cache, "Cache server port changed to %u", new->port);
673 return NEED_RESTART;
674 }
675
676 if (old->tr_config.type != new->tr_config.type)
677 {
678 CACHE_TRACE(D_EVENTS, cache, "Transport type changed");
679 return NEED_RESTART;
680 }
681
682 if (old->ignore_max_length != new->ignore_max_length)
683 {
684 CACHE_TRACE(D_EVENTS, cache, "Ignore max length changed");
685 try_reset = 1;
686 }
687
688 #if HAVE_LIBSSH
689 else if (new->tr_config.type == RPKI_TR_SSH)
690 {
691 struct rpki_tr_ssh_config *ssh_old = (void *) old->tr_config.spec;
692 struct rpki_tr_ssh_config *ssh_new = (void *) new->tr_config.spec;
693 if (bstrcmp(ssh_old->bird_private_key, ssh_new->bird_private_key) ||
694 bstrcmp(ssh_old->cache_public_key, ssh_new->cache_public_key) ||
695 bstrcmp(ssh_old->user, ssh_new->user))
696 {
697 CACHE_TRACE(D_EVENTS, cache, "Settings of SSH transport configuration changed");
698 try_fast_reconnect = 1;
699 }
700 }
701 #endif
702
703 #define TEST_INTERVAL(name, Name) \
704 if (old->name##_interval != new->name##_interval || \
705 old->keep_##name##_interval != new->keep_##name##_interval) \
706 { \
707 cache->name##_interval = new->name##_interval; \
708 CACHE_TRACE(D_EVENTS, cache, #Name " interval changed to %u seconds %s", cache->name##_interval, (new->keep_##name##_interval ? "and keep it" : "")); \
709 try_fast_reconnect = 1; \
710 }
711 TEST_INTERVAL(refresh, Refresh);
712 TEST_INTERVAL(retry, Retry);
713 TEST_INTERVAL(expire, Expire);
714 #undef TEST_INTERVAL
715
716 if (try_reset || try_fast_reconnect)
717 {
718 if (cache->state != RPKI_CS_ESTABLISHED)
719 return NEED_RESTART;
720
721 if (try_reset && !try_fast_reconnect)
722 rpki_cache_change_state(cache, RPKI_CS_RESET);
723
724 if (try_fast_reconnect)
725 {
726 if (try_reset)
727 {
728 /* Force reset during reconnect */
729 cache->request_session_id = 1;
730 cache->serial_num = 0;
731 }
732
733 rpki_cache_change_state(cache, RPKI_CS_FAST_RECONNECT);
734 }
735 }
736
737 return SUCCESSFUL_RECONF;
738 }
739
740 /**
741 * rpki_reconfigure - a protocol reconfiguration hook
742 * @P: a protocol instance
743 * @CF: a new protocol configuration
744 *
745 * This function reconfigures whole protocol.
746 * It sets new protocol configuration into a protocol structure.
747 * Returns |NEED_TO_RESTART| or |SUCCESSFUL_RECONF|.
748 */
749 static int
750 rpki_reconfigure(struct proto *P, struct proto_config *CF)
751 {
752 struct rpki_proto *p = (void *) P;
753 struct rpki_config *new = (void *) CF;
754 struct rpki_config *old = (void *) p->p.cf;
755 struct rpki_cache *cache = p->cache;
756
757 if (!proto_configure_channel(&p->p, &p->roa4_channel, proto_cf_find_channel(CF, NET_ROA4)) ||
758 !proto_configure_channel(&p->p, &p->roa6_channel, proto_cf_find_channel(CF, NET_ROA6)))
759 return NEED_RESTART;
760
761 if (rpki_reconfigure_cache(p, cache, new, old) != SUCCESSFUL_RECONF)
762 return NEED_RESTART;
763
764 return SUCCESSFUL_RECONF;
765 }
766
767
768 /*
769 * RPKI Protocol Glue
770 */
771
772 static struct proto *
773 rpki_init(struct proto_config *CF)
774 {
775 struct proto *P = proto_new(CF);
776 struct rpki_proto *p = (void *) P;
777
778 proto_configure_channel(&p->p, &p->roa4_channel, proto_cf_find_channel(CF, NET_ROA4));
779 proto_configure_channel(&p->p, &p->roa6_channel, proto_cf_find_channel(CF, NET_ROA6));
780
781 return P;
782 }
783
784 static int
785 rpki_start(struct proto *P)
786 {
787 struct rpki_proto *p = (void *) P;
788 struct rpki_config *cf = (void *) P->cf;
789
790 p->cache = rpki_init_cache(p, cf);
791 rpki_start_cache(p->cache);
792
793 return PS_START;
794 }
795
796 static void
797 rpki_get_status(struct proto *P, byte *buf)
798 {
799 struct rpki_proto *p = (struct rpki_proto *) P;
800
801 if (P->proto_state == PS_DOWN)
802 {
803 *buf = 0;
804 return;
805 }
806
807 if (p->cache)
808 bsprintf(buf, "%s", rpki_cache_state_to_str(p->cache->state));
809 else
810 bsprintf(buf, "No cache server configured");
811 }
812
813 static void
814 rpki_show_proto_info_timer(const char *name, uint num, timer *t)
815 {
816 if (tm_active(t))
817 cli_msg(-1006, " %-16s: %t/%u", name, tm_remains(t), num);
818 else
819 cli_msg(-1006, " %-16s: ---", name);
820 }
821
822 static void
823 rpki_show_proto_info(struct proto *P)
824 {
825 struct rpki_proto *p = (struct rpki_proto *) P;
826 struct rpki_config *cf = (void *) p->p.cf;
827 struct rpki_cache *cache = p->cache;
828
829 if (P->proto_state == PS_DOWN)
830 return;
831
832 if (cache)
833 {
834 const char *transport_name = "---";
835 uint default_port = 0;
836
837 switch (cf->tr_config.type)
838 {
839 #if HAVE_LIBSSH
840 case RPKI_TR_SSH:
841 transport_name = "SSHv2";
842 default_port = RPKI_SSH_PORT;
843 break;
844 #endif
845 case RPKI_TR_TCP:
846 transport_name = "Unprotected over TCP";
847 default_port = RPKI_TCP_PORT;
848 break;
849 };
850
851 cli_msg(-1006, " Cache server: %s", cf->hostname);
852
853 if (cf->port != default_port)
854 cli_msg(-1006, " Cache port: %u", cf->port);
855
856 cli_msg(-1006, " Status: %s", rpki_cache_state_to_str(cache->state));
857 cli_msg(-1006, " Transport: %s", transport_name);
858 cli_msg(-1006, " Protocol version: %u", cache->version);
859
860 if (cache->request_session_id)
861 cli_msg(-1006, " Session ID: ---");
862 else
863 cli_msg(-1006, " Session ID: %u", cache->session_id);
864
865 if (cache->last_update)
866 {
867 cli_msg(-1006, " Serial number: %u", cache->serial_num);
868 cli_msg(-1006, " Last update: before %t s", current_time() - cache->last_update);
869 }
870 else
871 {
872 cli_msg(-1006, " Serial number: ---");
873 cli_msg(-1006, " Last update: ---");
874 }
875
876 rpki_show_proto_info_timer("Refresh timer", cache->refresh_interval, cache->refresh_timer);
877 rpki_show_proto_info_timer("Retry timer", cache->retry_interval, cache->retry_timer);
878 rpki_show_proto_info_timer("Expire timer", cache->expire_interval, cache->expire_timer);
879
880 if (p->roa4_channel)
881 channel_show_info(p->roa4_channel);
882 else
883 cli_msg(-1006, " No roa4 channel");
884
885 if (p->roa6_channel)
886 channel_show_info(p->roa6_channel);
887 else
888 cli_msg(-1006, " No roa6 channel");
889 }
890 }
891
892
893 /*
894 * RPKI Protocol Configuration
895 */
896
897 /**
898 * rpki_check_config - check and complete configuration of RPKI protocol
899 * @cf: RPKI configuration
900 *
901 * This function is called at the end of parsing RPKI protocol configuration.
902 */
903 void
904 rpki_check_config(struct rpki_config *cf)
905 {
906 /* Do not check templates at all */
907 if (cf->c.class == SYM_TEMPLATE)
908 return;
909
910 if (ipa_zero(cf->ip) && cf->hostname == NULL)
911 cf_error("IP address or hostname of cache server must be set");
912
913 /* Set default transport type */
914 if (cf->tr_config.spec == NULL)
915 {
916 cf->tr_config.spec = cfg_allocz(sizeof(struct rpki_tr_tcp_config));
917 cf->tr_config.type = RPKI_TR_TCP;
918 }
919
920 if (cf->port == 0)
921 {
922 /* Set default port numbers */
923 switch (cf->tr_config.type)
924 {
925 #if HAVE_LIBSSH
926 case RPKI_TR_SSH:
927 cf->port = RPKI_SSH_PORT;
928 break;
929 #endif
930 default:
931 cf->port = RPKI_TCP_PORT;
932 }
933 }
934 }
935
936 static void
937 rpki_postconfig(struct proto_config *CF)
938 {
939 /* Define default channel */
940 if (EMPTY_LIST(CF->channels))
941 cf_error("Channel not specified");
942 }
943
944 static void
945 rpki_copy_config(struct proto_config *dest UNUSED, struct proto_config *src UNUSED)
946 {
947 /* FIXME: Should copy transport */
948 }
949
950 struct protocol proto_rpki = {
951 .name = "RPKI",
952 .template = "rpki%d",
953 .class = PROTOCOL_RPKI,
954 .preference = DEF_PREF_RPKI,
955 .proto_size = sizeof(struct rpki_proto),
956 .config_size = sizeof(struct rpki_config),
957 .init = rpki_init,
958 .start = rpki_start,
959 .postconfig = rpki_postconfig,
960 .channel_mask = (NB_ROA4 | NB_ROA6),
961 .show_proto_info = rpki_show_proto_info,
962 .shutdown = rpki_shutdown,
963 .copy_config = rpki_copy_config,
964 .reconfigure = rpki_reconfigure,
965 .get_status = rpki_get_status,
966 };
967
968 void
969 rpki_build(void)
970 {
971 proto_build(&proto_rpki);
972 }