File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird2 / proto / rpki / packets.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Oct 21 16:03:56 2019 UTC (5 years, 5 months ago) by misho
Branches: bird2, MAIN
CVS tags: v2_0_7p0, HEAD
bird2 ver 2.0.7

    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:  *	This file was a part of RTRlib: http://rpki.realmv6.org/
    8:  *
    9:  *	Can be freely distributed and used under the terms of the GNU GPL.
   10:  */
   11: 
   12: #include <stdlib.h>
   13: #include <string.h>
   14: #include <stdio.h>
   15: 
   16: #undef LOCAL_DEBUG
   17: 
   18: #include "rpki.h"
   19: #include "transport.h"
   20: #include "packets.h"
   21: 
   22: #define RPKI_ADD_FLAG 		0b00000001
   23: 
   24: enum rpki_transmit_type {
   25:   RPKI_RECV 			= 0,
   26:   RPKI_SEND 			= 1,
   27: };
   28: 
   29: enum pdu_error_type {
   30:   CORRUPT_DATA 			= 0,
   31:   INTERNAL_ERROR 		= 1,
   32:   NO_DATA_AVAIL 		= 2,
   33:   INVALID_REQUEST 		= 3,
   34:   UNSUPPORTED_PROTOCOL_VER 	= 4,
   35:   UNSUPPORTED_PDU_TYPE 		= 5,
   36:   WITHDRAWAL_OF_UNKNOWN_RECORD 	= 6,
   37:   DUPLICATE_ANNOUNCEMENT 	= 7,
   38:   PDU_TOO_BIG 			= 32
   39: };
   40: 
   41: static const char *str_pdu_error_type[] = {
   42:   [CORRUPT_DATA] 		= "Corrupt-Data",
   43:   [INTERNAL_ERROR] 		= "Internal-Error",
   44:   [NO_DATA_AVAIL] 		= "No-Data-Available",
   45:   [INVALID_REQUEST] 		= "Invalid-Request",
   46:   [UNSUPPORTED_PROTOCOL_VER] 	= "Unsupported-Protocol-Version",
   47:   [UNSUPPORTED_PDU_TYPE] 	= "Unsupported-PDU-Type",
   48:   [WITHDRAWAL_OF_UNKNOWN_RECORD]= "Withdrawal-Of-Unknown-Record",
   49:   [DUPLICATE_ANNOUNCEMENT] 	= "Duplicate-Announcement",
   50:   [PDU_TOO_BIG] 		= "PDU-Too-Big",
   51: };
   52: 
   53: enum pdu_type {
   54:   SERIAL_NOTIFY 		= 0,
   55:   SERIAL_QUERY 			= 1,
   56:   RESET_QUERY 			= 2,
   57:   CACHE_RESPONSE 		= 3,
   58:   IPV4_PREFIX 			= 4,
   59:   RESERVED 			= 5,
   60:   IPV6_PREFIX			= 6,
   61:   END_OF_DATA 			= 7,
   62:   CACHE_RESET 			= 8,
   63:   ROUTER_KEY 			= 9,
   64:   ERROR 			= 10,
   65:   PDU_TYPE_MAX
   66: };
   67: 
   68: static const char *str_pdu_type_[] = {
   69:   [SERIAL_NOTIFY] 		= "Serial Notify",
   70:   [SERIAL_QUERY] 		= "Serial Query",
   71:   [RESET_QUERY] 		= "Reset Query",
   72:   [CACHE_RESPONSE] 		= "Cache Response",
   73:   [IPV4_PREFIX] 		= "IPv4 Prefix",
   74:   [RESERVED] 			= "Reserved",
   75:   [IPV6_PREFIX] 		= "IPv6 Prefix",
   76:   [END_OF_DATA] 		= "End of Data",
   77:   [CACHE_RESET] 		= "Cache Reset",
   78:   [ROUTER_KEY] 			= "Router Key",
   79:   [ERROR] 			= "Error"
   80: };
   81: 
   82: static const char *str_pdu_type(uint type) {
   83:   if (type < PDU_TYPE_MAX)
   84:     return str_pdu_type_[type];
   85:   else
   86:     return "Undefined packet type";
   87: }
   88: 
   89: /*
   90:  *  0          8          16         24        31
   91:  * .-------------------------------------------.
   92:  * | Protocol |   PDU    |                     |
   93:  * | Version  |   Type   |    reserved = zero  |
   94:  * |  0 or 1  |  0 - 10  |                     |
   95:  * +-------------------------------------------+
   96:  * |                                           |
   97:  * |                 Length >= 8               |
   98:  * |                                           |
   99:  * `-------------------------------------------' */
  100: struct pdu_header {
  101:   u8 ver;
  102:   u8 type;
  103:   u16 reserved;
  104:   u32 len;
  105: } PACKED;
  106: 
  107: struct pdu_cache_response {
  108:   u8 ver;
  109:   u8 type;
  110:   u16 session_id;
  111:   u32 len;
  112: } PACKED;
  113: 
  114: struct pdu_serial_notify {
  115:   u8 ver;
  116:   u8 type;
  117:   u16 session_id;
  118:   u32 len;
  119:   u32 serial_num;
  120: } PACKED;
  121: 
  122: struct pdu_serial_query {
  123:   u8 ver;
  124:   u8 type;
  125:   u16 session_id;
  126:   u32 len;
  127:   u32 serial_num;
  128: } PACKED;
  129: 
  130: struct pdu_ipv4 {
  131:   u8 ver;
  132:   u8 type;
  133:   u16 reserved;
  134:   u32 len;
  135:   u8 flags;
  136:   u8 prefix_len;
  137:   u8 max_prefix_len;
  138:   u8 zero;
  139:   ip4_addr prefix;
  140:   u32 asn;
  141: } PACKED;
  142: 
  143: struct pdu_ipv6 {
  144:   u8 ver;
  145:   u8 type;
  146:   u16 reserved;
  147:   u32 len;
  148:   u8 flags;
  149:   u8 prefix_len;
  150:   u8 max_prefix_len;
  151:   u8 zero;
  152:   ip6_addr prefix;
  153:   u32 asn;
  154: } PACKED;
  155: 
  156: /*
  157:  *  0          8          16         24        31
  158:  *  .-------------------------------------------.
  159:  *  | Protocol |   PDU    |                     |
  160:  *  | Version  |   Type   |     Error Code      |
  161:  *  |    1     |    10    |                     |
  162:  *  +-------------------------------------------+
  163:  *  |                                           |
  164:  *  |                  Length                   |
  165:  *  |                                           |
  166:  *  +-------------------------------------------+
  167:  *  |                                           |
  168:  *  |       Length of Encapsulated PDU          |
  169:  *  |                                           |
  170:  *  +-------------------------------------------+
  171:  *  |                                           |
  172:  *  ~           Copy of Erroneous PDU           ~
  173:  *  |                                           |
  174:  *  +-------------------------------------------+
  175:  *  |                                           |
  176:  *  |           Length of Error Text            |
  177:  *  |                                           |
  178:  *  +-------------------------------------------+
  179:  *  |                                           |
  180:  *  |              Arbitrary Text               |
  181:  *  |                    of                     |
  182:  *  ~          Error Diagnostic Message         ~
  183:  *  |                                           |
  184:  *  `-------------------------------------------' */
  185: struct pdu_error {
  186:   u8 ver;
  187:   u8 type;
  188:   u16 error_code;
  189:   u32 len;
  190:   u32 len_enc_pdu;		/* Length of Encapsulated PDU */
  191:   byte rest[];			/* Copy of Erroneous PDU
  192: 				 * Length of Error Text
  193: 				 * Error Diagnostic Message */
  194: } PACKED;
  195: 
  196: struct pdu_reset_query {
  197:   u8 ver;
  198:   u8 type;
  199:   u16 flags;
  200:   u32 len;
  201: } PACKED;
  202: 
  203: struct pdu_end_of_data_v0 {
  204:   u8 ver;
  205:   u8 type;
  206:   u16 session_id;
  207:   u32 len;
  208:   u32 serial_num;
  209: } PACKED;
  210: 
  211: struct pdu_end_of_data_v1 {
  212:   u8 ver;
  213:   u8 type;
  214:   u16 session_id;
  215:   u32 len;
  216:   u32 serial_num;
  217:   u32 refresh_interval;
  218:   u32 retry_interval;
  219:   u32 expire_interval;
  220: } PACKED;
  221: 
  222: static const size_t min_pdu_size[] = {
  223:   [SERIAL_NOTIFY] 		= sizeof(struct pdu_serial_notify),
  224:   [SERIAL_QUERY] 		= sizeof(struct pdu_serial_query),
  225:   [RESET_QUERY] 		= sizeof(struct pdu_reset_query),
  226:   [CACHE_RESPONSE] 		= sizeof(struct pdu_cache_response),
  227:   [IPV4_PREFIX] 		= sizeof(struct pdu_ipv4),
  228:   [RESERVED] 			= sizeof(struct pdu_header),
  229:   [IPV6_PREFIX] 		= sizeof(struct pdu_ipv6),
  230:   [END_OF_DATA] 		= sizeof(struct pdu_end_of_data_v0),
  231:   [CACHE_RESET] 		= sizeof(struct pdu_cache_response),
  232:   [ROUTER_KEY] 			= sizeof(struct pdu_header), /* FIXME */
  233:   [ERROR] 			= 16,
  234: };
  235: 
  236: static int rpki_send_error_pdu(struct rpki_cache *cache, const enum pdu_error_type error_code, const u32 err_pdu_len, const struct pdu_header *erroneous_pdu, const char *fmt, ...);
  237: 
  238: static void
  239: rpki_pdu_to_network_byte_order(struct pdu_header *pdu)
  240: {
  241:   pdu->reserved = htons(pdu->reserved);
  242:   pdu->len = htonl(pdu->len);
  243: 
  244:   switch (pdu->type)
  245:   {
  246:   case SERIAL_QUERY:
  247:   {
  248:     /* Note that a session_id is converted using converting header->reserved */
  249:     struct pdu_serial_query *sq_pdu = (void *) pdu;
  250:     sq_pdu->serial_num = htonl(sq_pdu->serial_num);
  251:     break;
  252:   }
  253: 
  254:   case ERROR:
  255:   {
  256:     struct pdu_error *err = (void *) pdu;
  257:     u32 *err_text_len = (u32 *)(err->rest + err->len_enc_pdu);
  258:     *err_text_len = htonl(*err_text_len);
  259:     err->len_enc_pdu = htonl(err->len_enc_pdu);
  260:     break;
  261:   }
  262: 
  263:   case RESET_QUERY:
  264:     break;
  265: 
  266:   default:
  267:     bug("PDU type %s should not be sent by us", str_pdu_type(pdu->type));
  268:   }
  269: }
  270: 
  271: static void
  272: rpki_pdu_to_host_byte_order(struct pdu_header *pdu)
  273: {
  274:   /* The Router Key PDU has two one-byte fields instead of one two-bytes field. */
  275:   if (pdu->type != ROUTER_KEY)
  276:     pdu->reserved = ntohs(pdu->reserved);
  277: 
  278:   pdu->len = ntohl(pdu->len);
  279: 
  280:   switch (pdu->type)
  281:   {
  282:   case SERIAL_NOTIFY:
  283:   {
  284:     /* Note that a session_id is converted using converting header->reserved */
  285:     struct pdu_serial_notify *sn_pdu = (void *) pdu;
  286:     sn_pdu->serial_num = ntohl(sn_pdu->serial_num);
  287:     break;
  288:   }
  289: 
  290:   case END_OF_DATA:
  291:   {
  292:     /* Note that a session_id is converted using converting header->reserved */
  293:     struct pdu_end_of_data_v0 *eod0 = (void *) pdu;
  294:     eod0->serial_num = ntohl(eod0->serial_num); /* Same either for version 1 */
  295: 
  296:     if (pdu->ver == RPKI_VERSION_1)
  297:     {
  298:       struct pdu_end_of_data_v1 *eod1 = (void *) pdu;
  299:       eod1->expire_interval = ntohl(eod1->expire_interval);
  300:       eod1->refresh_interval = ntohl(eod1->refresh_interval);
  301:       eod1->retry_interval = ntohl(eod1->retry_interval);
  302:     }
  303:     break;
  304:   }
  305: 
  306:   case IPV4_PREFIX:
  307:   {
  308:     struct pdu_ipv4 *ipv4 = (void *) pdu;
  309:     ipv4->prefix = ip4_ntoh(ipv4->prefix);
  310:     ipv4->asn = ntohl(ipv4->asn);
  311:     break;
  312:   }
  313: 
  314:   case IPV6_PREFIX:
  315:   {
  316:     struct pdu_ipv6 *ipv6 = (void *) pdu;
  317:     ipv6->prefix = ip6_ntoh(ipv6->prefix);
  318:     ipv6->asn = ntohl(ipv6->asn);
  319:     break;
  320:   }
  321: 
  322:   case ERROR:
  323:   {
  324:     /* Note that a error_code is converted using converting header->reserved */
  325:     struct pdu_error *err = (void *) pdu;
  326:     err->len_enc_pdu = ntohl(err->len_enc_pdu);
  327:     u32 *err_text_len = (u32 *)(err->rest + err->len_enc_pdu);
  328:     *err_text_len = htonl(*err_text_len);
  329:     break;
  330:   }
  331: 
  332:   case ROUTER_KEY:
  333:     /* Router Key PDU is not supported yet */
  334: 
  335:   case SERIAL_QUERY:
  336:   case RESET_QUERY:
  337:     /* Serial/Reset Query are sent only in direction router to cache.
  338:      * We don't care here. */
  339: 
  340:   case CACHE_RESPONSE:
  341:   case CACHE_RESET:
  342:     /* Converted with pdu->reserved */
  343:     break;
  344:   }
  345: }
  346: 
  347: /**
  348:  * rpki_convert_pdu_back_to_network_byte_order - convert host-byte order PDU back to network-byte order
  349:  * @out: allocated memory for writing a converted PDU of size @in->len
  350:  * @in: host-byte order PDU
  351:  *
  352:  * Assumed: |A == ntoh(ntoh(A))|
  353:  */
  354: static struct pdu_header *
  355: rpki_pdu_back_to_network_byte_order(struct pdu_header *out, const struct pdu_header *in)
  356: {
  357:   memcpy(out, in, in->len);
  358:   rpki_pdu_to_host_byte_order(out);
  359:   return out;
  360: }
  361: 
  362: static void
  363: rpki_log_packet(struct rpki_cache *cache, const struct pdu_header *pdu, const enum rpki_transmit_type action)
  364: {
  365:   if (!(cache->p->p.debug & D_PACKETS))
  366:     return;
  367: 
  368:   const char *str_type = str_pdu_type(pdu->type);
  369:   char detail[256];
  370: 
  371: #define SAVE(fn)		\
  372:   do {				\
  373:     if (fn < 0) 		\
  374:     {				\
  375:       bsnprintf(detail + sizeof(detail) - 16, 16, "... <too long>)"); \
  376:       goto detail_finished;	\
  377:     }				\
  378:   } while(0)			\
  379: 
  380:   switch (pdu->type)
  381:   {
  382:   case SERIAL_NOTIFY:
  383:   case SERIAL_QUERY:
  384:     SAVE(bsnprintf(detail, sizeof(detail), "(session id: %u, serial number: %u)", pdu->reserved, ((struct pdu_serial_notify *) pdu)->serial_num));
  385:     break;
  386: 
  387:   case END_OF_DATA:
  388:   {
  389:     const struct pdu_end_of_data_v1 *eod = (void *) pdu;
  390:     if (eod->ver == RPKI_VERSION_1)
  391:       SAVE(bsnprintf(detail, sizeof(detail), "(session id: %u, serial number: %u, refresh: %us, retry: %us, expire: %us)", eod->session_id, eod->serial_num, eod->refresh_interval, eod->retry_interval, eod->expire_interval));
  392:     else
  393:       SAVE(bsnprintf(detail, sizeof(detail), "(session id: %u, serial number: %u)", eod->session_id, eod->serial_num));
  394:     break;
  395:   }
  396: 
  397:   case CACHE_RESPONSE:
  398:     SAVE(bsnprintf(detail, sizeof(detail), "(session id: %u)", pdu->reserved));
  399:     break;
  400: 
  401:   case IPV4_PREFIX:
  402:   {
  403:     const struct pdu_ipv4 *ipv4 = (void *) pdu;
  404:     SAVE(bsnprintf(detail, sizeof(detail), "(%I4/%u-%u AS%u)", ipv4->prefix, ipv4->prefix_len, ipv4->max_prefix_len, ipv4->asn));
  405:     break;
  406:   }
  407: 
  408:   case IPV6_PREFIX:
  409:   {
  410:     const struct pdu_ipv6 *ipv6 = (void *) pdu;
  411:     SAVE(bsnprintf(detail, sizeof(detail), "(%I6/%u-%u AS%u)", ipv6->prefix, ipv6->prefix_len, ipv6->max_prefix_len, ipv6->asn));
  412:     break;
  413:   }
  414: 
  415:   case ROUTER_KEY:
  416:     /* We don't support saving Router Key PDUs yet */
  417:     SAVE(bsnprintf(detail, sizeof(detail), "(ignored)"));
  418:     break;
  419: 
  420:   case ERROR:
  421:   {
  422:     const struct pdu_error *err = (void *) pdu;
  423:     SAVE(bsnprintf(detail, sizeof(detail), "(%s", str_pdu_error_type[err->error_code]));
  424: 
  425:     /* Optional description of error */
  426:     const u32 len_err_txt = *((u32 *) (err->rest + err->len_enc_pdu));
  427:     if (len_err_txt > 0)
  428:     {
  429:       size_t expected_len = err->len_enc_pdu + len_err_txt + 16;
  430:       if (expected_len == err->len)
  431:       {
  432:         char txt[len_err_txt + 1];
  433:         char *pdu_txt = (char *) err->rest + err->len_enc_pdu + 4;
  434:         bsnprintf(txt, sizeof(txt), "%s", pdu_txt); /* it's ensured that txt is ended with a null byte */
  435:         SAVE(bsnprintf(detail + strlen(detail), sizeof(detail) - strlen(detail), ": '%s'", txt));
  436:       }
  437:       else
  438:       {
  439: 	SAVE(bsnprintf(detail + strlen(detail), sizeof(detail) - strlen(detail), ", malformed size"));
  440:       }
  441:     }
  442: 
  443:     /* Optional encapsulated erroneous packet */
  444:     if (err->len_enc_pdu)
  445:     {
  446:       SAVE(bsnprintf(detail + strlen(detail), sizeof(detail) - strlen(detail), ", %s packet:", str_pdu_type(((struct pdu_header *) err->rest)->type)));
  447:       if (err->rest + err->len_enc_pdu <= (byte *)err + err->len)
  448:       {
  449: 	for (const byte *c = err->rest; c != err->rest + err->len_enc_pdu; c++)
  450: 	  SAVE(bsnprintf(detail + strlen(detail), sizeof(detail) - strlen(detail), " %02X", *c));
  451:       }
  452:     }
  453: 
  454:     SAVE(bsnprintf(detail + strlen(detail), sizeof(detail) - strlen(detail), ")"));
  455:     break;
  456:   }
  457: 
  458:   default:
  459:     *detail = '\0';
  460:   }
  461: #undef SAVE
  462: 
  463:  detail_finished:
  464: 
  465:   if (action == RPKI_RECV)
  466:   {
  467:     CACHE_TRACE(D_PACKETS, cache, "Received %s packet %s", str_type, detail);
  468:   }
  469:   else
  470:   {
  471:     CACHE_TRACE(D_PACKETS, cache, "Sending %s packet %s", str_type, detail);
  472:   }
  473: 
  474: #if defined(LOCAL_DEBUG) || defined(GLOBAL_DEBUG)
  475:   int seq = 0;
  476:   for(const byte *c = pdu; c != pdu + pdu->len; c++)
  477:   {
  478:     if ((seq % 4) == 0)
  479:       DBG("%2d: ", seq);
  480: 
  481:     DBG("  0x%02X %-3u", *c, *c);
  482: 
  483:     if ((++seq % 4) == 0)
  484:       DBG("\n");
  485:   }
  486:   if ((seq % 4) != 0)
  487:     DBG("\n");
  488: #endif
  489: }
  490: 
  491: static int
  492: rpki_send_pdu(struct rpki_cache *cache, const void *pdu, const uint len)
  493: {
  494:   struct rpki_proto *p = cache->p;
  495:   sock *sk = cache->tr_sock->sk;
  496: 
  497:   rpki_log_packet(cache, pdu, RPKI_SEND);
  498: 
  499:   if (sk->tbuf != sk->tpos)
  500:   {
  501:     RPKI_WARN(p, "Old packet overwritten in TX buffer");
  502:   }
  503: 
  504:   if (len > sk->tbsize)
  505:   {
  506:     RPKI_WARN(p, "%u bytes is too much for send", len);
  507:     ASSERT(0);
  508:     return RPKI_ERROR;
  509:   }
  510: 
  511:   memcpy(sk->tbuf, pdu, len);
  512:   rpki_pdu_to_network_byte_order((void *) sk->tbuf);
  513: 
  514:   if (!sk_send(sk, len))
  515:   {
  516:     DBG("Cannot send just the whole data. It will be sent using a call of tx_hook()");
  517:   }
  518: 
  519:   return RPKI_SUCCESS;
  520: }
  521: 
  522: /**
  523:  * rpki_check_receive_packet - make a basic validation of received RPKI PDU header
  524:  * @cache: cache connection instance
  525:  * @pdu: RPKI PDU in network byte order
  526:  *
  527:  * This function checks protocol version, PDU type, version and size. If all is all right then
  528:  * function returns |RPKI_SUCCESS| otherwise sends Error PDU and returns
  529:  * |RPKI_ERROR|.
  530:  */
  531: static int
  532: rpki_check_receive_packet(struct rpki_cache *cache, const struct pdu_header *pdu)
  533: {
  534:   u32 pdu_len = ntohl(pdu->len);
  535: 
  536:   /*
  537:    * Minimal and maximal allowed PDU size is treated in rpki_rx_hook() function.
  538:    * @header.len corresponds to number of bytes of @pdu and
  539:    * it is in range from RPKI_PDU_HEADER_LEN to RPKI_PDU_MAX_LEN bytes.
  540:    */
  541: 
  542:   /* Do not handle error PDUs here, leave this task to rpki_handle_error_pdu() */
  543:   if (pdu->ver != cache->version && pdu->type != ERROR)
  544:   {
  545:     /* If this is the first PDU we have received */
  546:     if (cache->request_session_id)
  547:     {
  548:       if (pdu->type == SERIAL_NOTIFY)
  549:       {
  550: 	/*
  551: 	 * The router MUST ignore any Serial Notify PDUs it might receive from
  552: 	 * the cache during this initial start-up period, regardless of the
  553: 	 * Protocol Version field in the Serial Notify PDU.
  554: 	 * (https://tools.ietf.org/html/draft-ietf-sidr-rpki-rtr-rfc6810-bis-07#section-7)
  555: 	 */
  556:       }
  557:       else if (!cache->last_update &&
  558: 	       (pdu->ver <= RPKI_MAX_VERSION) &&
  559: 	       (pdu->ver < cache->version))
  560:       {
  561:         CACHE_TRACE(D_EVENTS, cache, "Downgrade session to %s from %u to %u version", rpki_get_cache_ident(cache), cache->version, pdu->ver);
  562:         cache->version = pdu->ver;
  563:       }
  564:       else
  565:       {
  566:         /* If this is not the first PDU we have received, something is wrong with
  567:          * the server implementation -> Error */
  568: 	rpki_send_error_pdu(cache, UNSUPPORTED_PROTOCOL_VER, pdu_len, pdu, "PDU with unsupported Protocol version received");
  569: 	return RPKI_ERROR;
  570:       }
  571:     }
  572:   }
  573: 
  574:   if ((pdu->type >= PDU_TYPE_MAX) || (pdu->ver == RPKI_VERSION_0 && pdu->type == ROUTER_KEY))
  575:   {
  576:     rpki_send_error_pdu(cache, UNSUPPORTED_PDU_TYPE, pdu_len, pdu, "Unsupported PDU type %u received", pdu->type);
  577:     return RPKI_ERROR;
  578:   }
  579: 
  580:   if (pdu_len < min_pdu_size[pdu->type])
  581:   {
  582:     rpki_send_error_pdu(cache, CORRUPT_DATA, pdu_len, pdu, "Received %s packet with %d bytes, but expected at least %d bytes", str_pdu_type(pdu->type), pdu_len, min_pdu_size[pdu->type]);
  583:     return RPKI_ERROR;
  584:   }
  585: 
  586:   return RPKI_SUCCESS;
  587: }
  588: 
  589: static int
  590: rpki_handle_error_pdu(struct rpki_cache *cache, const struct pdu_error *pdu)
  591: {
  592:   switch (pdu->error_code)
  593:   {
  594:   case CORRUPT_DATA:
  595:   case INTERNAL_ERROR:
  596:   case INVALID_REQUEST:
  597:   case UNSUPPORTED_PDU_TYPE:
  598:     rpki_cache_change_state(cache, RPKI_CS_ERROR_FATAL);
  599:     break;
  600: 
  601:   case NO_DATA_AVAIL:
  602:     rpki_cache_change_state(cache, RPKI_CS_ERROR_NO_DATA_AVAIL);
  603:     break;
  604: 
  605:   case UNSUPPORTED_PROTOCOL_VER:
  606:     CACHE_TRACE(D_PACKETS, cache, "Client uses unsupported protocol version");
  607:     if (pdu->ver <= RPKI_MAX_VERSION &&
  608: 	pdu->ver < cache->version)
  609:     {
  610:       CACHE_TRACE(D_EVENTS, cache, "Downgrading from protocol version %d to version %d", cache->version, pdu->ver);
  611:       cache->version = pdu->ver;
  612:       rpki_cache_change_state(cache, RPKI_CS_FAST_RECONNECT);
  613:     }
  614:     else
  615:     {
  616:       CACHE_TRACE(D_PACKETS, cache, "Got UNSUPPORTED_PROTOCOL_VER error PDU with invalid values, " \
  617: 		  "current version: %d, PDU version: %d", cache->version, pdu->ver);
  618:       rpki_cache_change_state(cache, RPKI_CS_ERROR_FATAL);
  619:     }
  620:     break;
  621: 
  622:   default:
  623:     CACHE_TRACE(D_PACKETS, cache, "Error unknown, server sent unsupported error code %u", pdu->error_code);
  624:     rpki_cache_change_state(cache, RPKI_CS_ERROR_FATAL);
  625:     break;
  626:   }
  627: 
  628:   return RPKI_SUCCESS;
  629: }
  630: 
  631: static void
  632: rpki_handle_serial_notify_pdu(struct rpki_cache *cache, const struct pdu_serial_notify *pdu)
  633: {
  634:   /* The router MUST ignore any Serial Notify PDUs it might receive from
  635:    * the cache during this initial start-up period, regardless of the
  636:    * Protocol Version field in the Serial Notify PDU.
  637:    * (https://tools.ietf.org/html/draft-ietf-sidr-rpki-rtr-rfc6810-bis-07#section-7)
  638:    */
  639:   if (cache->request_session_id)
  640:   {
  641:     CACHE_TRACE(D_PACKETS, cache, "Ignore a Serial Notify packet during initial start-up period");
  642:     return;
  643:   }
  644: 
  645:   /* XXX Serial number should be compared using method RFC 1982 (3.2) */
  646:   if (cache->serial_num != pdu->serial_num)
  647:     rpki_cache_change_state(cache, RPKI_CS_SYNC_START);
  648: }
  649: 
  650: static int
  651: rpki_handle_cache_response_pdu(struct rpki_cache *cache, const struct pdu_cache_response *pdu)
  652: {
  653:   if (cache->request_session_id)
  654:   {
  655:     if (cache->last_update)
  656:     {
  657:       /*
  658:        * This isn't the first sync and we already received records. This point
  659:        * is after Reset Query and before importing new records from cache
  660:        * server. We need to load new ones and kick out missing ones.  So start
  661:        * a refresh cycle.
  662:        */
  663:       if (cache->p->roa4_channel)
  664: 	rt_refresh_begin(cache->p->roa4_channel->table, cache->p->roa4_channel);
  665:       if (cache->p->roa6_channel)
  666: 	rt_refresh_begin(cache->p->roa6_channel->table, cache->p->roa6_channel);
  667: 
  668:       cache->p->refresh_channels = 1;
  669:     }
  670:     cache->session_id = pdu->session_id;
  671:     cache->request_session_id = 0;
  672:   }
  673:   else
  674:   {
  675:     if (cache->session_id != pdu->session_id)
  676:     {
  677:       byte tmp[pdu->len];
  678:       const struct pdu_header *hton_pdu = rpki_pdu_back_to_network_byte_order((void *) tmp, (const void *) pdu);
  679:       rpki_send_error_pdu(cache, CORRUPT_DATA, pdu->len, hton_pdu, "Wrong session_id %u in Cache Response PDU", pdu->session_id);
  680:       rpki_cache_change_state(cache, RPKI_CS_ERROR_FATAL);
  681:       return RPKI_ERROR;
  682:     }
  683:   }
  684: 
  685:   rpki_cache_change_state(cache, RPKI_CS_SYNC_RUNNING);
  686:   return RPKI_SUCCESS;
  687: }
  688: 
  689: /**
  690:  * rpki_prefix_pdu_2_net_addr - convert IPv4/IPv6 Prefix PDU into net_addr_union
  691:  * @pdu: host byte order IPv4/IPv6 Prefix PDU
  692:  * @n: allocated net_addr_union for save ROA
  693:  *
  694:  * This function reads ROA data from IPv4/IPv6 Prefix PDU and
  695:  * write them into net_addr_roa4 or net_addr_roa6 data structure.
  696:  */
  697: static net_addr_union *
  698: rpki_prefix_pdu_2_net_addr(const struct pdu_header *pdu, net_addr_union *n)
  699: {
  700:   /*
  701:    * Note that sizeof(net_addr_roa6) > sizeof(net_addr)
  702:    * and thence we must use net_addr_union and not only net_addr
  703:    */
  704: 
  705:   if (pdu->type == IPV4_PREFIX)
  706:   {
  707:     const struct pdu_ipv4 *ipv4 = (void *) pdu;
  708:     n->roa4.type = NET_ROA4;
  709:     n->roa4.length = sizeof(net_addr_roa4);
  710:     n->roa4.prefix = ipv4->prefix;
  711:     n->roa4.asn = ipv4->asn;
  712:     n->roa4.pxlen = ipv4->prefix_len;
  713:     n->roa4.max_pxlen = ipv4->max_prefix_len;
  714:   }
  715:   else
  716:   {
  717:     const struct pdu_ipv6 *ipv6 = (void *) pdu;
  718:     n->roa6.type = NET_ROA6;
  719:     n->roa6.length = sizeof(net_addr_roa6);
  720:     n->roa6.prefix = ipv6->prefix;
  721:     n->roa6.asn = ipv6->asn;
  722:     n->roa6.pxlen = ipv6->prefix_len;
  723:     n->roa6.max_pxlen = ipv6->max_prefix_len;
  724:   }
  725: 
  726:   return n;
  727: }
  728: 
  729: static int
  730: rpki_handle_prefix_pdu(struct rpki_cache *cache, const struct pdu_header *pdu)
  731: {
  732:   const enum pdu_type type = pdu->type;
  733:   ASSERT(type == IPV4_PREFIX || type == IPV6_PREFIX);
  734: 
  735:   net_addr_union addr = {};
  736:   rpki_prefix_pdu_2_net_addr(pdu, &addr);
  737: 
  738:   struct channel *channel = NULL;
  739: 
  740:   if (type == IPV4_PREFIX)
  741:     channel = cache->p->roa4_channel;
  742:   if (type == IPV6_PREFIX)
  743:     channel = cache->p->roa6_channel;
  744: 
  745:   if (!channel)
  746:   {
  747:     CACHE_TRACE(D_ROUTES, cache, "Skip %N, missing %s channel", &addr, (type == IPV4_PREFIX ? "roa4" : "roa6"), addr);
  748:     return RPKI_ERROR;
  749:   }
  750: 
  751:   cache->last_rx_prefix = current_time();
  752: 
  753:   /* A place for 'flags' is same for both data structures pdu_ipv4 or pdu_ipv6  */
  754:   struct pdu_ipv4 *pfx = (void *) pdu;
  755:   if (pfx->flags & RPKI_ADD_FLAG)
  756:     rpki_table_add_roa(cache, channel, &addr);
  757:   else
  758:     rpki_table_remove_roa(cache, channel, &addr);
  759: 
  760:   return RPKI_SUCCESS;
  761: }
  762: 
  763: static uint
  764: rpki_check_interval(struct rpki_cache *cache, const char *(check_fn)(uint), uint interval)
  765: {
  766:   if (check_fn(interval))
  767:   {
  768:     RPKI_WARN(cache->p, "%s, received %u seconds", check_fn(interval), interval);
  769:     return 0;
  770:   }
  771:   return 1;
  772: }
  773: 
  774: static void
  775: rpki_handle_end_of_data_pdu(struct rpki_cache *cache, const struct pdu_end_of_data_v1 *pdu)
  776: {
  777:   const struct rpki_config *cf = (void *) cache->p->p.cf;
  778: 
  779:   if (pdu->session_id != cache->session_id)
  780:   {
  781:     byte tmp[pdu->len];
  782:     const struct pdu_header *hton_pdu = rpki_pdu_back_to_network_byte_order((void *) tmp, (const void *) pdu);
  783:     rpki_send_error_pdu(cache, CORRUPT_DATA, pdu->len, hton_pdu, "Received Session ID %u, but expected %u", pdu->session_id, cache->session_id);
  784:     rpki_cache_change_state(cache, RPKI_CS_ERROR_FATAL);
  785:     return;
  786:   }
  787: 
  788:   if (pdu->ver == RPKI_VERSION_1)
  789:   {
  790:     if (!cf->keep_refresh_interval && rpki_check_interval(cache, rpki_check_refresh_interval, pdu->refresh_interval))
  791:       cache->refresh_interval = pdu->refresh_interval;
  792: 
  793:     if (!cf->keep_retry_interval && rpki_check_interval(cache, rpki_check_retry_interval, pdu->retry_interval))
  794:           cache->retry_interval = pdu->retry_interval;
  795: 
  796:     if (!cf->keep_expire_interval && rpki_check_interval(cache, rpki_check_expire_interval, pdu->expire_interval))
  797:       cache->expire_interval = pdu->expire_interval;
  798: 
  799:     CACHE_TRACE(D_EVENTS, cache, "New interval values: "
  800: 		"refresh: %s%us, "
  801: 		"retry: %s%us, "
  802: 		"expire: %s%us",
  803: 		(cf->keep_refresh_interval ? "keeps " : ""), cache->refresh_interval,
  804: 		(cf->keep_retry_interval ? "keeps " : ""),   cache->retry_interval,
  805: 		(cf->keep_expire_interval ? "keeps " : ""),  cache->expire_interval);
  806:   }
  807: 
  808:   if (cache->p->refresh_channels)
  809:   {
  810:     cache->p->refresh_channels = 0;
  811:     if (cache->p->roa4_channel)
  812:       rt_refresh_end(cache->p->roa4_channel->table, cache->p->roa4_channel);
  813:     if (cache->p->roa6_channel)
  814:       rt_refresh_end(cache->p->roa6_channel->table, cache->p->roa6_channel);
  815:   }
  816: 
  817:   cache->last_update = current_time();
  818:   cache->serial_num = pdu->serial_num;
  819:   rpki_cache_change_state(cache, RPKI_CS_ESTABLISHED);
  820: }
  821: 
  822: /**
  823:  * rpki_rx_packet - process a received RPKI PDU
  824:  * @cache: RPKI connection instance
  825:  * @pdu: a RPKI PDU in network byte order
  826:  */
  827: static void
  828: rpki_rx_packet(struct rpki_cache *cache, struct pdu_header *pdu)
  829: {
  830:   struct rpki_proto *p = cache->p;
  831: 
  832:   if (rpki_check_receive_packet(cache, pdu) == RPKI_ERROR)
  833:   {
  834:     rpki_cache_change_state(cache, RPKI_CS_ERROR_FATAL);
  835:     return;
  836:   }
  837: 
  838:   rpki_pdu_to_host_byte_order(pdu);
  839:   rpki_log_packet(cache, pdu, RPKI_RECV);
  840: 
  841:   switch (pdu->type)
  842:   {
  843:   case RESET_QUERY:
  844:   case SERIAL_QUERY:
  845:     RPKI_WARN(p, "Received a %s packet that is destined for cache server", str_pdu_type(pdu->type));
  846:     break;
  847: 
  848:   case SERIAL_NOTIFY:
  849:     /* This is a signal to synchronize with the cache server just now */
  850:     rpki_handle_serial_notify_pdu(cache, (void *) pdu);
  851:     break;
  852: 
  853:   case CACHE_RESPONSE:
  854:     rpki_handle_cache_response_pdu(cache, (void *) pdu);
  855:     break;
  856: 
  857:   case IPV4_PREFIX:
  858:   case IPV6_PREFIX:
  859:     rpki_handle_prefix_pdu(cache, pdu);
  860:     break;
  861: 
  862:   case END_OF_DATA:
  863:     rpki_handle_end_of_data_pdu(cache, (void *) pdu);
  864:     break;
  865: 
  866:   case CACHE_RESET:
  867:     /* Cache cannot provide an incremental update. */
  868:     rpki_cache_change_state(cache, RPKI_CS_NO_INCR_UPDATE_AVAIL);
  869:     break;
  870: 
  871:   case ERROR:
  872:     rpki_handle_error_pdu(cache, (void *) pdu);
  873:     break;
  874: 
  875:   case ROUTER_KEY:
  876:     /* TODO: Implement Router Key PDU handling */
  877:     break;
  878: 
  879:   default:
  880:     CACHE_TRACE(D_PACKETS, cache, "Received unsupported type (%u)", pdu->type);
  881:   };
  882: }
  883: 
  884: int
  885: rpki_rx_hook(struct birdsock *sk, uint size)
  886: {
  887:   struct rpki_cache *cache = sk->data;
  888:   struct rpki_proto *p = cache->p;
  889: 
  890:   byte *pkt_start = sk->rbuf;
  891:   byte *end = pkt_start + size;
  892: 
  893:   DBG("rx hook got %u bytes \n", size);
  894: 
  895:   while (end >= pkt_start + RPKI_PDU_HEADER_LEN)
  896:   {
  897:     struct pdu_header *pdu = (void *) pkt_start;
  898:     u32 pdu_size = ntohl(pdu->len);
  899: 
  900:     if (pdu_size < RPKI_PDU_HEADER_LEN || pdu_size > RPKI_PDU_MAX_LEN)
  901:     {
  902:       RPKI_WARN(p, "Received invalid packet length %u, purge the whole receiving buffer", pdu_size);
  903:       return 1; /* Purge recv buffer */
  904:     }
  905: 
  906:     if (end < pkt_start + pdu_size)
  907:       break;
  908: 
  909:     rpki_rx_packet(cache, pdu);
  910: 
  911:     /* It is possible that bird socket was freed/closed */
  912:     if (p->p.proto_state == PS_DOWN || sk != cache->tr_sock->sk)
  913:       return 0;
  914: 
  915:     pkt_start += pdu_size;
  916:   }
  917: 
  918:   if (pkt_start != sk->rbuf)
  919:   {
  920:     CACHE_DBG(cache, "Move %u bytes of a memory at the start of buffer", end - pkt_start);
  921:     memmove(sk->rbuf, pkt_start, end - pkt_start);
  922:     sk->rpos = sk->rbuf + (end - pkt_start);
  923:   }
  924: 
  925:   return 0; /* Not purge sk->rbuf */
  926: }
  927: 
  928: void
  929: rpki_err_hook(struct birdsock *sk, int error_num)
  930: {
  931:   struct rpki_cache *cache = sk->data;
  932: 
  933:   if (error_num)
  934:   {
  935:     /* sk->err may contains a SSH error description */
  936:     if (sk->err)
  937:       CACHE_TRACE(D_EVENTS, cache, "Lost connection: %s", sk->err);
  938:     else
  939:       CACHE_TRACE(D_EVENTS, cache, "Lost connection: %M", error_num);
  940:   }
  941:   else
  942:   {
  943:     CACHE_TRACE(D_EVENTS, cache, "The other side closed a connection");
  944:   }
  945: 
  946: 
  947:   rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
  948: }
  949: 
  950: static int
  951: rpki_fire_tx(struct rpki_cache *cache)
  952: {
  953:   sock *sk = cache->tr_sock->sk;
  954: 
  955:   uint bytes_to_send = sk->tpos - sk->tbuf;
  956:   DBG("Sending %u bytes", bytes_to_send);
  957:   return sk_send(sk, bytes_to_send);
  958: }
  959: 
  960: void
  961: rpki_tx_hook(sock *sk)
  962: {
  963:   struct rpki_cache *cache = sk->data;
  964: 
  965:   while (rpki_fire_tx(cache) > 0)
  966:     ;
  967: }
  968: 
  969: void
  970: rpki_connected_hook(sock *sk)
  971: {
  972:   struct rpki_cache *cache = sk->data;
  973: 
  974:   CACHE_TRACE(D_EVENTS, cache, "Connected");
  975:   proto_notify_state(&cache->p->p, PS_UP);
  976: 
  977:   sk->rx_hook = rpki_rx_hook;
  978:   sk->tx_hook = rpki_tx_hook;
  979: 
  980:   rpki_cache_change_state(cache, RPKI_CS_SYNC_START);
  981: }
  982: 
  983: /**
  984:  * rpki_send_error_pdu - send RPKI Error PDU
  985:  * @cache: RPKI connection instance
  986:  * @error_code: PDU Error type
  987:  * @err_pdu_len: length of @erroneous_pdu
  988:  * @erroneous_pdu: optional network byte-order PDU that invokes Error by us or NULL
  989:  * @fmt: optional description text of error or NULL
  990:  * @args: optional arguments for @fmt
  991:  *
  992:  * This function prepares Error PDU and sends it to a cache server.
  993:  */
  994: static int
  995: rpki_send_error_pdu(struct rpki_cache *cache, const enum pdu_error_type error_code, const u32 err_pdu_len, const struct pdu_header *erroneous_pdu, const char *fmt, ...)
  996: {
  997:   va_list args;
  998:   char msg[128];
  999: 
 1000:   /* Size including the terminating null byte ('\0') */
 1001:   int msg_len = 0;
 1002: 
 1003:   /* Don't send errors for erroneous error PDUs */
 1004:   if (err_pdu_len >= 2)
 1005:   {
 1006:     if (erroneous_pdu->type == ERROR)
 1007:       return RPKI_SUCCESS;
 1008:   }
 1009: 
 1010:   if (fmt)
 1011:   {
 1012:     va_start(args, fmt);
 1013:     msg_len = bvsnprintf(msg, sizeof(msg), fmt, args) + 1;
 1014:   }
 1015: 
 1016:   u32 pdu_size = 16 + err_pdu_len + msg_len;
 1017:   byte pdu[pdu_size];
 1018:   memset(pdu, 0, sizeof(pdu));
 1019: 
 1020:   struct pdu_error *e = (void *) pdu;
 1021:   e->ver = cache->version;
 1022:   e->type = ERROR;
 1023:   e->error_code = error_code;
 1024:   e->len = pdu_size;
 1025: 
 1026:   e->len_enc_pdu = err_pdu_len;
 1027:   if (err_pdu_len > 0)
 1028:     memcpy(e->rest, erroneous_pdu, err_pdu_len);
 1029: 
 1030:   *((u32 *)(e->rest + err_pdu_len)) = msg_len;
 1031:   if (msg_len > 0)
 1032:     memcpy(e->rest + err_pdu_len + 4, msg, msg_len);
 1033: 
 1034:   return rpki_send_pdu(cache, pdu, pdu_size);
 1035: }
 1036: 
 1037: int
 1038: rpki_send_serial_query(struct rpki_cache *cache)
 1039: {
 1040:   struct pdu_serial_query pdu = {
 1041:     .ver = cache->version,
 1042:     .type = SERIAL_QUERY,
 1043:     .session_id = cache->session_id,
 1044:     .len = sizeof(pdu),
 1045:     .serial_num = cache->serial_num
 1046:   };
 1047: 
 1048:   if (rpki_send_pdu(cache, &pdu, sizeof(pdu)) != RPKI_SUCCESS)
 1049:   {
 1050:     rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
 1051:     return RPKI_ERROR;
 1052:   }
 1053: 
 1054:   return RPKI_SUCCESS;
 1055: }
 1056: 
 1057: int
 1058: rpki_send_reset_query(struct rpki_cache *cache)
 1059: {
 1060:   struct pdu_reset_query pdu = {
 1061:     .ver = cache->version,
 1062:     .type = RESET_QUERY,
 1063:     .len = sizeof(pdu),
 1064:   };
 1065: 
 1066:   if (rpki_send_pdu(cache, &pdu, sizeof(pdu)) != RPKI_SUCCESS)
 1067:   {
 1068:     rpki_cache_change_state(cache, RPKI_CS_ERROR_TRANSPORT);
 1069:     return RPKI_ERROR;
 1070:   }
 1071: 
 1072:   return RPKI_SUCCESS;
 1073: }

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