Annotation of embedaddon/bird2/proto/rpki/rpki.c, revision 1.1.1.1

1.1       misho       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:     .src = p->p.main_source,
                    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);
                    132: 
                    133:   e->pflags = 0;
                    134: 
                    135:   rte_update2(channel, &pfxr->n, e, a0.src);
                    136: }
                    137: 
                    138: void
                    139: rpki_table_remove_roa(struct rpki_cache *cache, struct channel *channel, const net_addr_union *pfxr)
                    140: {
                    141:   struct rpki_proto *p = cache->p;
                    142:   rte_update2(channel, &pfxr->n, NULL, p->p.main_source);
                    143: }
                    144: 
                    145: 
                    146: /*
                    147:  *     RPKI Protocol Logic
                    148:  */
                    149: 
                    150: static const char *str_cache_states[] = {
                    151:   [RPKI_CS_CONNECTING]                 = "Connecting",
                    152:   [RPKI_CS_ESTABLISHED]        = "Established",
                    153:   [RPKI_CS_RESET]              = "Reseting",
                    154:   [RPKI_CS_SYNC_START]                 = "Sync-Start",
                    155:   [RPKI_CS_SYNC_RUNNING]       = "Sync-Running",
                    156:   [RPKI_CS_FAST_RECONNECT]     = "Fast-Reconnect",
                    157:   [RPKI_CS_NO_INCR_UPDATE_AVAIL]= "No-Increment-Update-Available",
                    158:   [RPKI_CS_ERROR_NO_DATA_AVAIL] = "Cache-Error-No-Data-Available",
                    159:   [RPKI_CS_ERROR_FATAL]        = "Fatal-Protocol-Error",
                    160:   [RPKI_CS_ERROR_TRANSPORT]    = "Transport-Error",
                    161:   [RPKI_CS_SHUTDOWN]           = "Down"
                    162: };
                    163: 
                    164: /**
                    165:  * rpki_cache_state_to_str - give a text representation of cache state
                    166:  * @state: A cache state
                    167:  *
                    168:  * The function converts logic cache state into string.
                    169:  */
                    170: const char *
                    171: rpki_cache_state_to_str(enum rpki_cache_state state)
                    172: {
                    173:   return str_cache_states[state];
                    174: }
                    175: 
                    176: /**
                    177:  * rpki_start_cache - connect to a cache server
                    178:  * @cache: RPKI connection instance
                    179:  *
                    180:  * This function is a high level method to kick up a connection to a cache server.
                    181:  */
                    182: static void
                    183: rpki_start_cache(struct rpki_cache *cache)
                    184: {
                    185:   rpki_cache_change_state(cache, RPKI_CS_CONNECTING);
                    186: }
                    187: 
                    188: /**
                    189:  * rpki_force_restart_proto - force shutdown and start protocol again
                    190:  * @p: RPKI protocol instance
                    191:  *
                    192:  * This function calls shutdown and frees all protocol resources as well.
                    193:  * After calling this function should be no operations with protocol data,
                    194:  * they could be freed already.
                    195:  */
                    196: static void
                    197: rpki_force_restart_proto(struct rpki_proto *p)
                    198: {
                    199:   if (p->cache)
                    200:   {
                    201:     CACHE_DBG(p->cache, "Connection object destroying");
                    202:   }
                    203: 
                    204:   /* Sign as freed */
                    205:   p->cache = NULL;
                    206: 
                    207:   proto_notify_state(&p->p, PS_DOWN);
                    208: }
                    209: 
                    210: /**
                    211:  * rpki_cache_change_state - check and change cache state
                    212:  * @cache: RPKI cache instance
                    213:  * @new_state: suggested new state
                    214:  *
                    215:  * This function makes transitions between internal states.
                    216:  * It represents the core of logic management of RPKI protocol.
                    217:  * Cannot transit into the same state as cache is in already.
                    218:  */
                    219: void
                    220: rpki_cache_change_state(struct rpki_cache *cache, const enum rpki_cache_state new_state)
                    221: {
                    222:   const enum rpki_cache_state old_state = cache->state;
                    223: 
                    224:   if (old_state == new_state)
                    225:     return;
                    226: 
                    227:   cache->state = new_state;
                    228:   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));
                    229: 
                    230:   switch (new_state)
                    231:   {
                    232:   case RPKI_CS_CONNECTING:
                    233:   {
                    234:     sock *sk = cache->tr_sock->sk;
                    235: 
                    236:     if (sk == NULL || sk->fd < 0)
                    237:       rpki_open_connection(cache);
                    238:     else
                    239:       rpki_cache_change_state(cache, RPKI_CS_SYNC_START);
                    240: 
                    241:     rpki_schedule_next_retry(cache);
                    242:     break;
                    243:   }
                    244: 
                    245:   case RPKI_CS_ESTABLISHED:
                    246:     rpki_schedule_next_refresh(cache);
                    247:     rpki_schedule_next_expire_check(cache);
                    248:     rpki_stop_retry_timer_event(cache);
                    249:     break;
                    250: 
                    251:   case RPKI_CS_RESET:
                    252:     /* Resetting cache connection. */
                    253:     cache->request_session_id = 1;
                    254:     cache->serial_num = 0;
                    255:     rpki_cache_change_state(cache, RPKI_CS_SYNC_START);
                    256:     break;
                    257: 
                    258:   case RPKI_CS_SYNC_START:
                    259:     /* Requesting for receive ROAs from a cache server. */
                    260:     if (cache->request_session_id)
                    261:     {
                    262:       /* Send request for Session ID */
                    263:       if (rpki_send_reset_query(cache) != RPKI_SUCCESS)
                    264:        rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
                    265:     }
                    266:     else
                    267:     {
                    268:       /* We have already a session_id. So send a Serial Query and start an incremental sync */
                    269:       if (rpki_send_serial_query(cache) != RPKI_SUCCESS)
                    270:        rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
                    271:     }
                    272:     break;
                    273: 
                    274:   case RPKI_CS_SYNC_RUNNING:
                    275:     /* The state between Cache Response and End of Data. Only waiting for
                    276:      * receiving all IP Prefix PDUs and finally a End of Data PDU. */
                    277:     break;
                    278: 
                    279:   case RPKI_CS_NO_INCR_UPDATE_AVAIL:
                    280:     /* Server was unable to answer the last Serial Query and sent Cache Reset. */
                    281:     rpki_cache_change_state(cache, RPKI_CS_RESET);
                    282:     break;
                    283: 
                    284:   case RPKI_CS_ERROR_NO_DATA_AVAIL:
                    285:     /* No validation records are available on the cache server. */
                    286:     rpki_cache_change_state(cache, RPKI_CS_RESET);
                    287:     break;
                    288: 
                    289:   case RPKI_CS_ERROR_FATAL:
                    290:     /* Fatal protocol error occurred. */
                    291:     rpki_force_restart_proto(cache->p);
                    292:     break;
                    293: 
                    294:   case RPKI_CS_ERROR_TRANSPORT:
                    295:     /* Error on the transport socket occurred. */
                    296:     rpki_close_connection(cache);
                    297:     rpki_schedule_next_retry(cache);
                    298:     rpki_stop_refresh_timer_event(cache);
                    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_do_we_recv_prefix_pdu_in_last_seconds(struct rpki_cache *cache)
                    370: {
                    371:   if (!cache->last_rx_prefix)
                    372:     return 0;
                    373: 
                    374:   return ((current_time() - cache->last_rx_prefix) <= 2 S);
                    375: }
                    376: 
                    377: /**
                    378:  * rpki_refresh_hook - control a scheduling of downloading data from cache server
                    379:  * @tm: refresh timer with cache connection instance in data
                    380:  *
                    381:  * This function is periodically called during &ESTABLISHED or &SYNC* state
                    382:  * cache connection.  The first refresh schedule is invoked after receiving a
                    383:  * |End of Data| PDU and has run by some &ERROR is occurred.
                    384:  */
                    385: static void
                    386: rpki_refresh_hook(timer *tm)
                    387: {
                    388:   struct rpki_cache *cache = tm->data;
                    389: 
                    390:   CACHE_DBG(cache, "%s", rpki_cache_state_to_str(cache->state));
                    391: 
                    392:   switch (cache->state)
                    393:   {
                    394:   case RPKI_CS_ESTABLISHED:
                    395:     rpki_cache_change_state(cache, RPKI_CS_SYNC_START);
                    396:     break;
                    397: 
                    398:   case RPKI_CS_SYNC_START:
                    399:     /* We sent Serial/Reset Query in last refresh hook call
                    400:      * and didn't receive Cache Response yet. It is probably
                    401:      * troubles with network. */
                    402:   case RPKI_CS_SYNC_RUNNING:
                    403:     /* We sent Serial/Reset Query in last refresh hook call
                    404:      * and we got Cache Response but didn't get End-Of-Data yet.
                    405:      * It could be a trouble with network or only too long synchronization. */
                    406:     if (!rpki_do_we_recv_prefix_pdu_in_last_seconds(cache))
                    407:     {
                    408:       CACHE_TRACE(D_EVENTS, cache, "Sync takes more time than refresh interval %us, resetting connection", cache->refresh_interval);
                    409:       rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
                    410:     }
                    411:     break;
                    412: 
                    413:   default:
                    414:     break;
                    415:   }
                    416: 
                    417:   if (cache->state != RPKI_CS_SHUTDOWN && cache->state != RPKI_CS_ERROR_TRANSPORT)
                    418:     rpki_schedule_next_refresh(cache);
                    419:   else
                    420:     rpki_stop_refresh_timer_event(cache);
                    421: }
                    422: 
                    423: /**
                    424:  * rpki_retry_hook - control a scheduling of retrying connection to cache server
                    425:  * @tm: retry timer with cache connection instance in data
                    426:  *
                    427:  * This function is periodically called during &ERROR* state cache connection.
                    428:  * The first retry schedule is invoked after any &ERROR* state occurred and
                    429:  * ends by reaching of &ESTABLISHED state again.
                    430:  */
                    431: static void
                    432: rpki_retry_hook(timer *tm)
                    433: {
                    434:   struct rpki_cache *cache = tm->data;
                    435: 
                    436:   CACHE_DBG(cache, "%s", rpki_cache_state_to_str(cache->state));
                    437: 
                    438:   switch (cache->state)
                    439:   {
                    440:   case RPKI_CS_ESTABLISHED:
                    441:   case RPKI_CS_SHUTDOWN:
                    442:     break;
                    443: 
                    444:   case RPKI_CS_CONNECTING:
                    445:   case RPKI_CS_SYNC_START:
                    446:   case RPKI_CS_SYNC_RUNNING:
                    447:     if (!rpki_do_we_recv_prefix_pdu_in_last_seconds(cache))
                    448:     {
                    449:       /* We tried to establish a connection in last retry hook call and haven't done
                    450:        * yet. It looks like troubles with network. We are aggressive here. */
                    451:       CACHE_TRACE(D_EVENTS, cache, "Sync takes more time than retry interval %us, resetting connection.", cache->retry_interval);
                    452:       rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
                    453:     }
                    454:     break;
                    455: 
                    456:   default:
                    457:     rpki_cache_change_state(cache, RPKI_CS_CONNECTING);
                    458:     break;
                    459:   }
                    460: 
                    461:   if (cache->state != RPKI_CS_ESTABLISHED)
                    462:     rpki_schedule_next_retry(cache);
                    463:   else
                    464:     rpki_stop_retry_timer_event(cache);
                    465: }
                    466: 
                    467: /**
                    468:  * rpki_expire_hook - control a expiration of ROA entries
                    469:  * @tm: expire timer with cache connection instance in data
                    470:  *
                    471:  * This function is scheduled after received a |End of Data| PDU.
                    472:  * A waiting interval is calculated dynamically by last update.
                    473:  * If we reach an expiration time then we invoke a restarting
                    474:  * of the protocol.
                    475:  */
                    476: static void
                    477: rpki_expire_hook(timer *tm)
                    478: {
                    479:   struct rpki_cache *cache = tm->data;
                    480: 
                    481:   if (!cache->last_update)
                    482:     return;
                    483: 
                    484:   CACHE_DBG(cache, "%s", rpki_cache_state_to_str(cache->state));
                    485: 
                    486:   btime t = cache->last_update + cache->expire_interval S - current_time();
                    487:   if (t <= 0)
                    488:   {
                    489:     CACHE_TRACE(D_EVENTS, cache, "All ROAs expired");
                    490:     rpki_force_restart_proto(cache->p);
                    491:   }
                    492:   else
                    493:   {
                    494:     CACHE_DBG(cache, "Remains %t seconds to become ROAs obsolete", t);
                    495:     rpki_schedule_next_expire_check(cache);
                    496:   }
                    497: }
                    498: 
                    499: /**
                    500:  * rpki_check_refresh_interval - check validity of refresh interval value
                    501:  * @seconds: suggested value
                    502:  *
                    503:  * This function validates value and should return |NULL|.
                    504:  * If the check doesn't pass then returns error message.
                    505:  */
                    506: const char *
                    507: rpki_check_refresh_interval(uint seconds)
                    508: {
                    509:   if (seconds < 1)
                    510:     return "Minimum allowed refresh interval is 1 second";
                    511:   if (seconds > 86400)
                    512:     return "Maximum allowed refresh interval is 86400 seconds";
                    513:   return NULL;
                    514: }
                    515: 
                    516: /**
                    517:  * rpki_check_retry_interval - check validity of retry interval value
                    518:  * @seconds: suggested value
                    519:  *
                    520:  * This function validates value and should return |NULL|.
                    521:  * If the check doesn't pass then returns error message.
                    522:  */
                    523: const char *
                    524: rpki_check_retry_interval(uint seconds)
                    525: {
                    526:   if (seconds < 1)
                    527:     return "Minimum allowed retry interval is 1 second";
                    528:   if (seconds > 7200)
                    529:     return "Maximum allowed retry interval is 7200 seconds";
                    530:   return NULL;
                    531: }
                    532: 
                    533: /**
                    534:  * rpki_check_expire_interval - check validity of expire interval value
                    535:  * @seconds: suggested value
                    536:  *
                    537:  * This function validates value and should return |NULL|.
                    538:  * If the check doesn't pass then returns error message.
                    539:  */
                    540: const char *
                    541: rpki_check_expire_interval(uint seconds)
                    542: {
                    543:   if (seconds < 600)
                    544:     return "Minimum allowed expire interval is 600 seconds";
                    545:   if (seconds > 172800)
                    546:     return "Maximum allowed expire interval is 172800 seconds";
                    547:   return NULL;
                    548: }
                    549: 
                    550: 
                    551: /*
                    552:  *     RPKI Cache
                    553:  */
                    554: 
                    555: static struct rpki_cache *
                    556: rpki_init_cache(struct rpki_proto *p, struct rpki_config *cf)
                    557: {
                    558:   pool *pool = rp_new(p->p.pool, cf->hostname);
                    559: 
                    560:   struct rpki_cache *cache = mb_allocz(pool, sizeof(struct rpki_cache));
                    561: 
                    562:   cache->pool = pool;
                    563:   cache->p = p;
                    564: 
                    565:   cache->state = RPKI_CS_SHUTDOWN;
                    566:   cache->request_session_id = 1;
                    567:   cache->version = RPKI_MAX_VERSION;
                    568: 
                    569:   cache->refresh_interval = cf->refresh_interval;
                    570:   cache->retry_interval = cf->retry_interval;
                    571:   cache->expire_interval = cf->expire_interval;
                    572:   cache->refresh_timer = tm_new_init(pool, &rpki_refresh_hook, cache, 0, 0);
                    573:   cache->retry_timer = tm_new_init(pool, &rpki_retry_hook, cache, 0, 0);
                    574:   cache->expire_timer = tm_new_init(pool, &rpki_expire_hook, cache, 0, 0);
                    575: 
                    576:   cache->tr_sock = mb_allocz(pool, sizeof(struct rpki_tr_sock));
                    577:   cache->tr_sock->cache = cache;
                    578: 
                    579:   switch (cf->tr_config.type)
                    580:   {
                    581:   case RPKI_TR_TCP: rpki_tr_tcp_init(cache->tr_sock); break;
                    582:   case RPKI_TR_SSH: rpki_tr_ssh_init(cache->tr_sock); break;
                    583:   };
                    584: 
                    585:   CACHE_DBG(cache, "Connection object created");
                    586: 
                    587:   return cache;
                    588: }
                    589: 
                    590: /**
                    591:  * rpki_get_cache_ident - give a text representation of cache server name
                    592:  * @cache: RPKI connection instance
                    593:  *
                    594:  * The function converts cache connection into string.
                    595:  */
                    596: const char *
                    597: rpki_get_cache_ident(struct rpki_cache *cache)
                    598: {
                    599:   return rpki_tr_ident(cache->tr_sock);
                    600: }
                    601: 
                    602: static int
                    603: rpki_open_connection(struct rpki_cache *cache)
                    604: {
                    605:   CACHE_TRACE(D_EVENTS, cache, "Opening a connection");
                    606: 
                    607:   if (rpki_tr_open(cache->tr_sock) == RPKI_TR_ERROR)
                    608:   {
                    609:     rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
                    610:     return RPKI_TR_ERROR;
                    611:   }
                    612: 
                    613:   return RPKI_TR_SUCCESS;
                    614: }
                    615: 
                    616: static void
                    617: rpki_close_connection(struct rpki_cache *cache)
                    618: {
                    619:   CACHE_TRACE(D_EVENTS, cache, "Closing a connection");
                    620:   rpki_tr_close(cache->tr_sock);
                    621:   proto_notify_state(&cache->p->p, PS_START);
                    622: }
                    623: 
                    624: static int
                    625: rpki_shutdown(struct proto *P)
                    626: {
                    627:   struct rpki_proto *p = (void *) P;
                    628: 
                    629:   rpki_force_restart_proto(p);
                    630: 
                    631:   /* Protocol memory pool will be automatically freed */
                    632:   return PS_DOWN;
                    633: }
                    634: 
                    635: 
                    636: /*
                    637:  *     RPKI Reconfiguration
                    638:  */
                    639: 
                    640: static int
                    641: rpki_try_fast_reconnect(struct rpki_cache *cache)
                    642: {
                    643:   if (cache->state == RPKI_CS_ESTABLISHED)
                    644:   {
                    645:     rpki_cache_change_state(cache, RPKI_CS_FAST_RECONNECT);
                    646:     return SUCCESSFUL_RECONF;
                    647:   }
                    648: 
                    649:   return NEED_RESTART;
                    650: }
                    651: 
                    652: /**
                    653:  * rpki_reconfigure_cache - a cache reconfiguration
                    654:  * @p: RPKI protocol instance
                    655:  * @cache: a cache connection
                    656:  * @new: new RPKI configuration
                    657:  * @old: old RPKI configuration
                    658:  *
                    659:  * This function reconfigures existing single cache server connection with new
                    660:  * existing configuration.  Generally, a change of time intervals could be
                    661:  * reconfigured without restarting and all others changes requires a restart of
                    662:  * protocol.  Returns |NEED_TO_RESTART| or |SUCCESSFUL_RECONF|.
                    663:  */
                    664: static int
                    665: rpki_reconfigure_cache(struct rpki_proto *p UNUSED, struct rpki_cache *cache, struct rpki_config *new, struct rpki_config *old)
                    666: {
                    667:   u8 try_fast_reconnect = 0;
                    668: 
                    669:   if (strcmp(old->hostname, new->hostname) != 0)
                    670:   {
                    671:     CACHE_TRACE(D_EVENTS, cache, "Cache server address changed to %s", new->hostname);
                    672:     return NEED_RESTART;
                    673:   }
                    674: 
                    675:   if (old->port != new->port)
                    676:   {
                    677:     CACHE_TRACE(D_EVENTS, cache, "Cache server port changed to %u", new->port);
                    678:     return NEED_RESTART;
                    679:   }
                    680: 
                    681:   if (old->tr_config.type != new->tr_config.type)
                    682:   {
                    683:     CACHE_TRACE(D_EVENTS, cache, "Transport type changed");
                    684:     return NEED_RESTART;
                    685:   }
                    686:   else if (new->tr_config.type == RPKI_TR_SSH)
                    687:   {
                    688:     struct rpki_tr_ssh_config *ssh_old = (void *) old->tr_config.spec;
                    689:     struct rpki_tr_ssh_config *ssh_new = (void *) new->tr_config.spec;
                    690:     if (bstrcmp(ssh_old->bird_private_key, ssh_new->bird_private_key) ||
                    691:        bstrcmp(ssh_old->cache_public_key, ssh_new->cache_public_key) ||
                    692:        bstrcmp(ssh_old->user, ssh_new->user))
                    693:     {
                    694:       CACHE_TRACE(D_EVENTS, cache, "Settings of SSH transport configuration changed");
                    695:       try_fast_reconnect = 1;
                    696:     }
                    697:   }
                    698: 
                    699: #define TEST_INTERVAL(name, Name)                                              \
                    700:     if (cache->name##_interval != new->name##_interval ||                      \
                    701:        old->keep_##name##_interval != new->keep_##name##_interval)             \
                    702:     {                                                                          \
                    703:       cache->name##_interval = new->name##_interval;                           \
                    704:       CACHE_TRACE(D_EVENTS, cache, #Name " interval changed to %u seconds %s", cache->name##_interval, (new->keep_##name##_interval ? "and keep it" : "")); \
                    705:       try_fast_reconnect = 1;                                                  \
                    706:     }
                    707:   TEST_INTERVAL(refresh, Refresh);
                    708:   TEST_INTERVAL(retry, Retry);
                    709:   TEST_INTERVAL(expire, Expire);
                    710: #undef TEST_INTERVAL
                    711: 
                    712:   if (try_fast_reconnect)
                    713:     return rpki_try_fast_reconnect(cache);
                    714: 
                    715:   return SUCCESSFUL_RECONF;
                    716: }
                    717: 
                    718: /**
                    719:  * rpki_reconfigure - a protocol reconfiguration hook
                    720:  * @P: a protocol instance
                    721:  * @CF: a new protocol configuration
                    722:  *
                    723:  * This function reconfigures whole protocol.
                    724:  * It sets new protocol configuration into a protocol structure.
                    725:  * Returns |NEED_TO_RESTART| or |SUCCESSFUL_RECONF|.
                    726:  */
                    727: static int
                    728: rpki_reconfigure(struct proto *P, struct proto_config *CF)
                    729: {
                    730:   struct rpki_proto *p = (void *) P;
                    731:   struct rpki_config *new = (void *) CF;
                    732:   struct rpki_config *old = (void *) p->p.cf;
                    733:   struct rpki_cache *cache = p->cache;
                    734: 
                    735:   if (!proto_configure_channel(&p->p, &p->roa4_channel, proto_cf_find_channel(CF, NET_ROA4)) ||
                    736:       !proto_configure_channel(&p->p, &p->roa6_channel, proto_cf_find_channel(CF, NET_ROA6)))
                    737:     return NEED_RESTART;
                    738: 
                    739:   if (rpki_reconfigure_cache(p, cache, new, old) != SUCCESSFUL_RECONF)
                    740:     return NEED_RESTART;
                    741: 
                    742:   return SUCCESSFUL_RECONF;
                    743: }
                    744: 
                    745: 
                    746: /*
                    747:  *     RPKI Protocol Glue
                    748:  */
                    749: 
                    750: static struct proto *
                    751: rpki_init(struct proto_config *CF)
                    752: {
                    753:   struct proto *P = proto_new(CF);
                    754:   struct rpki_proto *p = (void *) P;
                    755: 
                    756:   proto_configure_channel(&p->p, &p->roa4_channel, proto_cf_find_channel(CF, NET_ROA4));
                    757:   proto_configure_channel(&p->p, &p->roa6_channel, proto_cf_find_channel(CF, NET_ROA6));
                    758: 
                    759:   return P;
                    760: }
                    761: 
                    762: static int
                    763: rpki_start(struct proto *P)
                    764: {
                    765:   struct rpki_proto *p = (void *) P;
                    766:   struct rpki_config *cf = (void *) P->cf;
                    767: 
                    768:   p->cache = rpki_init_cache(p, cf);
                    769:   rpki_start_cache(p->cache);
                    770: 
                    771:   return PS_START;
                    772: }
                    773: 
                    774: static void
                    775: rpki_get_status(struct proto *P, byte *buf)
                    776: {
                    777:   struct rpki_proto *p = (struct rpki_proto *) P;
                    778: 
                    779:   if (P->proto_state == PS_DOWN)
                    780:   {
                    781:     *buf = 0;
                    782:     return;
                    783:   }
                    784: 
                    785:   if (p->cache)
                    786:     bsprintf(buf, "%s", rpki_cache_state_to_str(p->cache->state));
                    787:   else
                    788:     bsprintf(buf, "No cache server configured");
                    789: }
                    790: 
                    791: static void
                    792: rpki_show_proto_info_timer(const char *name, uint num, timer *t)
                    793: {
                    794:   if (tm_active(t))
                    795:     cli_msg(-1006, "  %-16s: %t/%u", name, tm_remains(t), num);
                    796:   else
                    797:     cli_msg(-1006, "  %-16s: ---", name);
                    798: }
                    799: 
                    800: static void
                    801: rpki_show_proto_info(struct proto *P)
                    802: {
                    803:   struct rpki_proto *p = (struct rpki_proto *) P;
                    804:   struct rpki_config *cf = (void *) p->p.cf;
                    805:   struct rpki_cache *cache = p->cache;
                    806: 
                    807:   if (P->proto_state == PS_DOWN)
                    808:     return;
                    809: 
                    810:   if (cache)
                    811:   {
                    812:     const char *transport_name = "---";
                    813: 
                    814:     switch (cf->tr_config.type)
                    815:     {
                    816:     case RPKI_TR_SSH: transport_name = "SSHv2"; break;
                    817:     case RPKI_TR_TCP: transport_name = "Unprotected over TCP"; break;
                    818:     };
                    819: 
                    820:     cli_msg(-1006, "  Cache server:     %s", rpki_get_cache_ident(cache));
                    821:     cli_msg(-1006, "  Status:           %s", rpki_cache_state_to_str(cache->state));
                    822:     cli_msg(-1006, "  Transport:        %s", transport_name);
                    823:     cli_msg(-1006, "  Protocol version: %u", cache->version);
                    824: 
                    825:     if (cache->request_session_id)
                    826:       cli_msg(-1006, "  Session ID:       ---");
                    827:     else
                    828:       cli_msg(-1006, "  Session ID:       %u", cache->session_id);
                    829: 
                    830:     if (cache->last_update)
                    831:     {
                    832:       cli_msg(-1006, "  Serial number:    %u", cache->serial_num);
                    833:       cli_msg(-1006, "  Last update:      before %t s", current_time() - cache->last_update);
                    834:     }
                    835:     else
                    836:     {
                    837:       cli_msg(-1006, "  Serial number:    ---");
                    838:       cli_msg(-1006, "  Last update:      ---");
                    839:     }
                    840: 
                    841:     rpki_show_proto_info_timer("Refresh timer", cache->refresh_interval, cache->refresh_timer);
                    842:     rpki_show_proto_info_timer("Retry timer", cache->retry_interval, cache->retry_timer);
                    843:     rpki_show_proto_info_timer("Expire timer", cache->expire_interval, cache->expire_timer);
                    844: 
                    845:     if (p->roa4_channel)
                    846:       channel_show_info(p->roa4_channel);
                    847:     else
                    848:       cli_msg(-1006, "  No roa4 channel");
                    849: 
                    850:     if (p->roa6_channel)
                    851:       channel_show_info(p->roa6_channel);
                    852:     else
                    853:       cli_msg(-1006, "  No roa6 channel");
                    854:   }
                    855: }
                    856: 
                    857: 
                    858: /*
                    859:  *     RPKI Protocol Configuration
                    860:  */
                    861: 
                    862: /**
                    863:  * rpki_check_config - check and complete configuration of RPKI protocol
                    864:  * @cf: RPKI configuration
                    865:  *
                    866:  * This function is called at the end of parsing RPKI protocol configuration.
                    867:  */
                    868: void
                    869: rpki_check_config(struct rpki_config *cf)
                    870: {
                    871:   /* Do not check templates at all */
                    872:   if (cf->c.class == SYM_TEMPLATE)
                    873:     return;
                    874: 
                    875:   if (ipa_zero(cf->ip) && cf->hostname == NULL)
                    876:     cf_error("IP address or hostname of cache server must be set");
                    877: 
                    878:   /* Set default transport type */
                    879:   if (cf->tr_config.spec == NULL)
                    880:   {
                    881:     cf->tr_config.spec = cfg_allocz(sizeof(struct rpki_tr_tcp_config));
                    882:     cf->tr_config.type = RPKI_TR_TCP;
                    883:   }
                    884: 
                    885:   if (cf->port == 0)
                    886:   {
                    887:     /* Set default port numbers */
                    888:     switch (cf->tr_config.type)
                    889:     {
                    890:     case RPKI_TR_SSH:
                    891:       cf->port = RPKI_SSH_PORT;
                    892:       break;
                    893:     default:
                    894:       cf->port = RPKI_TCP_PORT;
                    895:     }
                    896:   }
                    897: }
                    898: 
                    899: static void
                    900: rpki_postconfig(struct proto_config *CF)
                    901: {
                    902:   /* Define default channel */
                    903:   if (EMPTY_LIST(CF->channels))
                    904:     channel_config_new(NULL, net_label[CF->net_type], CF->net_type, CF);
                    905: }
                    906: 
                    907: static void
                    908: rpki_copy_config(struct proto_config *dest UNUSED, struct proto_config *src UNUSED)
                    909: {
                    910:   /* FIXME: Should copy transport */
                    911: }
                    912: 
                    913: struct protocol proto_rpki = {
                    914:   .name =              "RPKI",
                    915:   .template =          "rpki%d",
                    916:   .class =             PROTOCOL_RPKI,
                    917:   .preference =        DEF_PREF_RPKI,
                    918:   .proto_size =        sizeof(struct rpki_proto),
                    919:   .config_size =       sizeof(struct rpki_config),
                    920:   .init =              rpki_init,
                    921:   .start =             rpki_start,
                    922:   .postconfig =        rpki_postconfig,
                    923:   .channel_mask =      (NB_ROA4 | NB_ROA6),
                    924:   .show_proto_info =   rpki_show_proto_info,
                    925:   .shutdown =          rpki_shutdown,
                    926:   .copy_config =       rpki_copy_config,
                    927:   .reconfigure =       rpki_reconfigure,
                    928:   .get_status =        rpki_get_status,
                    929: };

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>