Annotation of embedaddon/bird2/proto/rpki/packets.c, revision 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:  *     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>