Return to packets.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / bird2 / proto / rpki |
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: * 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: }