From 9dad73886d82f5b97cf2831493228e9d320f7441 Mon Sep 17 00:00:00 2001 From: claudio Date: Wed, 10 Jan 2024 16:08:36 +0000 Subject: [PATCH] Improve rtr_send_error() so that there is no need to log_warnx() before. Now rtr_send_error() supports a format string for the error message so use this fact to make the error report better. OK tb@ --- usr.sbin/bgpd/rtr_proto.c | 315 ++++++++++++++++++-------------------- 1 file changed, 146 insertions(+), 169 deletions(-) diff --git a/usr.sbin/bgpd/rtr_proto.c b/usr.sbin/bgpd/rtr_proto.c index 5b65b167d76..a3e5d9654ff 100644 --- a/usr.sbin/bgpd/rtr_proto.c +++ b/usr.sbin/bgpd/rtr_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: rtr_proto.c,v 1.27 2024/01/09 15:13:49 claudio Exp $ */ +/* $OpenBSD: rtr_proto.c,v 1.28 2024/01/10 16:08:36 claudio Exp $ */ /* * Copyright (c) 2020 Claudio Jeker @@ -246,7 +246,7 @@ log_rtr_type(enum rtr_pdu_type type) case ERROR_REPORT: return "error report"; case ASPA: - return "aspa pdu"; + return "aspa"; default: snprintf(buf, sizeof(buf), "unknown %u", type); return buf; @@ -296,23 +296,33 @@ rtr_newmsg(struct rtr_session *rs, enum rtr_pdu_type type, uint32_t len, return NULL; } +static void rtr_send_error(struct rtr_session *, struct ibuf *, enum rtr_error, + const char *, ...) __attribute__((__format__ (printf, 4, 5))); + /* * Try to send an error PDU to cache, put connection into error * state. */ static void -rtr_send_error(struct rtr_session *rs, enum rtr_error err, char *msg, - struct ibuf *pdu) +rtr_send_error(struct rtr_session *rs, struct ibuf *pdu, enum rtr_error err, + const char *fmt, ...) { struct ibuf *buf; + va_list ap; size_t len = 0, mlen = 0; rs->last_sent_error = err; - if (msg != NULL) { - mlen = strlen(msg); - strlcpy(rs->last_sent_msg, msg, sizeof(rs->last_sent_msg)); - } else - memset(rs->last_sent_msg, 0, sizeof(rs->last_sent_msg)); + memset(rs->last_sent_msg, 0, sizeof(rs->last_sent_msg)); + if (fmt != NULL) { + va_start(ap, fmt); + vsnprintf(rs->last_sent_msg, sizeof(rs->last_sent_msg), + fmt, ap); + mlen = strlen(rs->last_sent_msg); + va_end(ap); + } + + log_warnx("rtr %s: sending error: %s%s%s", log_rtr(rs), + log_rtr_error(err), mlen > 0 ? ": " : "", rs->last_sent_msg); if (pdu != NULL) { ibuf_rewind(pdu); @@ -331,13 +341,10 @@ rtr_send_error(struct rtr_session *rs, enum rtr_error err, char *msg, } if (ibuf_add_n32(buf, mlen) == -1) goto fail; - if (ibuf_add(buf, msg, mlen) == -1) + if (ibuf_add(buf, rs->last_sent_msg, mlen) == -1) goto fail; ibuf_close(&rs->w, buf); - log_warnx("rtr %s: sending error: %s%s%s", log_rtr(rs), - log_rtr_error(err), msg ? ": " : "", msg ? msg : ""); - rtr_fsm(rs, RTR_EVNT_SEND_ERROR); return; @@ -352,12 +359,15 @@ rtr_send_reset_query(struct rtr_session *rs) struct ibuf *buf; buf = rtr_newmsg(rs, RESET_QUERY, 0, 0); - if (buf == NULL) { - log_warn("rtr %s: send reset query", log_rtr(rs)); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", NULL); - return; - } + if (buf == NULL) + goto fail; ibuf_close(&rs->w, buf); + return; + + fail: + rtr_send_error(rs, NULL, INTERNAL_ERROR, + "send %s: %s", log_rtr_type(RESET_QUERY), strerror(errno)); + ibuf_free(buf); } static void @@ -374,9 +384,9 @@ rtr_send_serial_query(struct rtr_session *rs) return; fail: - log_warn("rtr %s: send serial query", log_rtr(rs)); + rtr_send_error(rs, NULL, INTERNAL_ERROR, + "send %s: %s", log_rtr_type(SERIAL_QUERY), strerror(errno)); ibuf_free(buf); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", NULL); } /* @@ -388,10 +398,9 @@ rtr_check_session_id(struct rtr_session *rs, uint16_t session_id, struct rtr_header *rh, struct ibuf *pdu) { if (session_id != ntohs(rh->session_id)) { - log_warnx("rtr %s: received %s: bad session_id: %d != %d", - log_rtr(rs), log_rtr_type(rh->type), ntohs(rh->session_id), - session_id); - rtr_send_error(rs, CORRUPT_DATA, "bad session_id", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, + "%s: bad session_id %d (expected %d)", + log_rtr_type(rh->type), ntohs(rh->session_id), session_id); return -1; } return 0; @@ -416,9 +425,8 @@ rtr_parse_header(struct rtr_session *rs, struct ibuf *hdr, len = ntohl(rh.length); if (len > RTR_MAX_LEN) { - log_warnx("rtr %s: received %s: pdu too big: %zu byte", - log_rtr(rs), log_rtr_type(rh.type), len); - rtr_send_error(rs, CORRUPT_DATA, "pdu too big", hdr); + rtr_send_error(rs, hdr, CORRUPT_DATA, "%s: too big: %zu bytes", + log_rtr_type(rh.type), len); return -1; } @@ -435,9 +443,8 @@ rtr_parse_header(struct rtr_session *rs, struct ibuf *hdr, /* ignore SERIAL_NOTIFY */ break; default: - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(rh.type)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", hdr); + rtr_send_error(rs, hdr, CORRUPT_DATA, + "%s: out of context", log_rtr_type(rh.type)); return -1; } } else if (rh.version != rs->version && rh.type != ERROR_REPORT) { @@ -491,9 +498,8 @@ rtr_parse_header(struct rtr_session *rs, struct ibuf *hdr, goto badlen; break; default: - log_warnx("rtr %s: received unsupported pdu: type %s", - log_rtr(rs), log_rtr_type(rh.type)); - rtr_send_error(rs, UNSUPP_PDU_TYPE, NULL, hdr); + rtr_send_error(rs, hdr, UNSUPP_PDU_TYPE, "type %s", + log_rtr_type(rh.type)); return -1; } @@ -503,15 +509,13 @@ rtr_parse_header(struct rtr_session *rs, struct ibuf *hdr, return 0; badlen: - log_warnx("rtr %s: received %s: bad pdu length: %zu bytes", - log_rtr(rs), log_rtr_type(rh.type), len); - rtr_send_error(rs, CORRUPT_DATA, "bad length", hdr); + rtr_send_error(rs, hdr, CORRUPT_DATA, "%s: bad length: %zu bytes", + log_rtr_type(rh.type), len); return -1; badversion: - log_warnx("rtr %s: received %s message: unexpected version %d", - log_rtr(rs), log_rtr_type(rh.type), rh.version); - rtr_send_error(rs, UNEXP_PROTOCOL_VERS, NULL, hdr); + rtr_send_error(rs, hdr, UNEXP_PROTOCOL_VERS, "%s: version %d", + log_rtr_type(rh.type), rh.version); return -1; } @@ -524,12 +528,8 @@ rtr_parse_notify(struct rtr_session *rs, struct ibuf *pdu) if (rs->state == RTR_STATE_NEGOTIATION) return 0; - if (ibuf_get(pdu, ¬ify, sizeof(notify)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(SERIAL_NOTIFY)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, ¬ify, sizeof(notify)) == -1) + goto badlen; if (rtr_check_session_id(rs, rs->session_id, ¬ify.hdr, pdu) == -1) return -1; @@ -543,6 +543,11 @@ rtr_parse_notify(struct rtr_session *rs, struct ibuf *pdu) rtr_fsm(rs, RTR_EVNT_SERIAL_NOTIFY); return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(SERIAL_NOTIFY)); + return -1; } static int @@ -550,12 +555,8 @@ rtr_parse_cache_response(struct rtr_session *rs, struct ibuf *pdu) { struct rtr_response resp; - if (ibuf_get(pdu, &resp, sizeof(resp)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(CACHE_RESPONSE)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &resp, sizeof(resp)) == -1) + goto badlen; /* set session_id if not yet happened */ if (rs->session_id == -1) @@ -565,14 +566,18 @@ rtr_parse_cache_response(struct rtr_session *rs, struct ibuf *pdu) return -1; if (rs->state != RTR_STATE_ESTABLISHED) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(CACHE_RESPONSE)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(CACHE_RESPONSE)); return -1; } rtr_fsm(rs, RTR_EVNT_CACHE_RESPONSE); return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(CACHE_RESPONSE)); + return -1; } static int @@ -581,35 +586,27 @@ rtr_parse_ipv4_prefix(struct rtr_session *rs, struct ibuf *pdu) struct rtr_ipv4 ip4; struct roa *roa; - if (ibuf_get(pdu, &ip4, sizeof(ip4)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &ip4, sizeof(ip4)) == -1) + goto badlen; if (rtr_check_session_id(rs, 0, &ip4.hdr, pdu) == -1) return -1; if (rs->state != RTR_STATE_EXCHANGE) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(IPV4_PREFIX)); return -1; } if (ip4.prefixlen > 32 || ip4.maxlen > 32 || ip4.prefixlen > ip4.maxlen) { - log_warnx("rtr: %s: received %s: bad prefixlen / maxlen", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "bad prefixlen / maxlen", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, + "%s: bad prefixlen / maxlen", log_rtr_type(IPV4_PREFIX)); return -1; } if ((roa = calloc(1, sizeof(*roa))) == NULL) { - log_warn("rtr %s: received %s", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", NULL); + rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory"); return -1; } roa->aid = AID_INET; @@ -620,9 +617,8 @@ rtr_parse_ipv4_prefix(struct rtr_session *rs, struct ibuf *pdu) if (ip4.flags & FLAG_ANNOUNCE) { if (RB_INSERT(roa_tree, &rs->roa_set, roa) != NULL) { - log_warnx("rtr %s: received %s: duplicate announcement", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, DUP_REC_RECV, NULL, pdu); + rtr_send_error(rs, pdu, DUP_REC_RECV, "%s %s", + log_rtr_type(IPV4_PREFIX), log_roa(roa)); free(roa); return -1; } @@ -631,9 +627,8 @@ rtr_parse_ipv4_prefix(struct rtr_session *rs, struct ibuf *pdu) r = RB_FIND(roa_tree, &rs->roa_set, roa); if (r == NULL) { - log_warnx("rtr %s: received %s: unknown withdrawal", - log_rtr(rs), log_rtr_type(IPV4_PREFIX)); - rtr_send_error(rs, UNK_REC_WDRAWL, NULL, pdu); + rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s", + log_rtr_type(IPV4_PREFIX), log_roa(roa)); free(roa); return -1; } @@ -643,6 +638,11 @@ rtr_parse_ipv4_prefix(struct rtr_session *rs, struct ibuf *pdu) } return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(IPV4_PREFIX)); + return -1; } static int @@ -651,35 +651,27 @@ rtr_parse_ipv6_prefix(struct rtr_session *rs, struct ibuf *pdu) struct rtr_ipv6 ip6; struct roa *roa; - if (ibuf_get(pdu, &ip6, sizeof(ip6)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &ip6, sizeof(ip6)) == -1) + goto badlen; if (rtr_check_session_id(rs, 0, &ip6.hdr, pdu) == -1) return -1; if (rs->state != RTR_STATE_EXCHANGE) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(IPV6_PREFIX)); return -1; } if (ip6.prefixlen > 128 || ip6.maxlen > 128 || ip6.prefixlen > ip6.maxlen) { - log_warnx("rtr: %s: received %s: bad prefixlen / maxlen", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, CORRUPT_DATA, "bad prefixlen / maxlen", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, + "%s: bad prefixlen / maxlen", log_rtr_type(IPV6_PREFIX)); return -1; } if ((roa = calloc(1, sizeof(*roa))) == NULL) { - log_warn("rtr %s: received %s", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", NULL); + rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory"); return -1; } roa->aid = AID_INET6; @@ -690,9 +682,8 @@ rtr_parse_ipv6_prefix(struct rtr_session *rs, struct ibuf *pdu) if (ip6.flags & FLAG_ANNOUNCE) { if (RB_INSERT(roa_tree, &rs->roa_set, roa) != NULL) { - log_warnx("rtr %s: received %s: duplicate announcement", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, DUP_REC_RECV, NULL, pdu); + rtr_send_error(rs, pdu, DUP_REC_RECV, "%s %s", + log_rtr_type(IPV6_PREFIX), log_roa(roa)); free(roa); return -1; } @@ -701,9 +692,8 @@ rtr_parse_ipv6_prefix(struct rtr_session *rs, struct ibuf *pdu) r = RB_FIND(roa_tree, &rs->roa_set, roa); if (r == NULL) { - log_warnx("rtr %s: received %s: unknown withdrawal", - log_rtr(rs), log_rtr_type(IPV6_PREFIX)); - rtr_send_error(rs, UNK_REC_WDRAWL, NULL, pdu); + rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s", + log_rtr_type(IPV6_PREFIX), log_roa(roa)); free(roa); return -1; } @@ -712,6 +702,11 @@ rtr_parse_ipv6_prefix(struct rtr_session *rs, struct ibuf *pdu) free(roa); } return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(IPV6_PREFIX)); + return -1; } static int @@ -722,24 +717,16 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) struct aspa_set *aspa, *a; uint16_t cnt, i; - if (ibuf_get(pdu, &rtr_aspa, sizeof(rtr_aspa)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &rtr_aspa, sizeof(rtr_aspa)) == -1) + goto badlen; + cnt = ntohs(rtr_aspa.cnt); - if (ibuf_size(pdu) != cnt * sizeof(uint32_t)) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_size(pdu) != cnt * sizeof(uint32_t)) + goto badlen; if (rs->state != RTR_STATE_EXCHANGE) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(ASPA)); return -1; } @@ -751,9 +738,7 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) /* create aspa_set entry from the rtr aspa pdu */ if ((aspa = calloc(1, sizeof(*aspa))) == NULL) { - log_warn("rtr %s: received %s", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", NULL); + rtr_send_error(rs, NULL, INTERNAL_ERROR, "out of memory"); return -1; } aspa->as = ntohl(rtr_aspa.cas); @@ -761,20 +746,13 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) if (cnt > 0) { if ((aspa->tas = calloc(cnt, sizeof(uint32_t))) == NULL) { free_aspa(aspa); - log_warn("rtr %s: received %s", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, INTERNAL_ERROR, "out of memory", - NULL); + rtr_send_error(rs, NULL, INTERNAL_ERROR, + "out of memory"); return -1; } for (i = 0; i < cnt; i++) { - if (ibuf_get_n32(pdu, &aspa->tas[i]) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", - pdu); - return -1; - } + if (ibuf_get_n32(pdu, &aspa->tas[i]) == -1) + goto badlen; } } @@ -785,10 +763,8 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) free_aspa(a); if (RB_INSERT(aspa_tree, aspatree, aspa) != NULL) { - log_warnx("rtr %s: received %s: corrupt tree", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, INTERNAL_ERROR, - "corrupt aspa tree", NULL); + rtr_send_error(rs, NULL, INTERNAL_ERROR, + "corrupt aspa tree"); free_aspa(aspa); return -1; } @@ -796,9 +772,8 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) } else { a = RB_FIND(aspa_tree, aspatree, aspa); if (a == NULL) { - log_warnx("rtr %s: received %s: unknown withdrawal", - log_rtr(rs), log_rtr_type(ASPA)); - rtr_send_error(rs, UNK_REC_WDRAWL, NULL, pdu); + rtr_send_error(rs, pdu, UNK_REC_WDRAWL, "%s %s", + log_rtr_type(ASPA), log_aspa(aspa)); free_aspa(aspa); return -1; } @@ -808,6 +783,11 @@ rtr_parse_aspa(struct rtr_session *rs, struct ibuf *pdu) } return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(ASPA)); + return -1; } static int @@ -815,20 +795,15 @@ rtr_parse_end_of_data_v0(struct rtr_session *rs, struct ibuf *pdu) { struct rtr_endofdata_v0 eod; - if (ibuf_get(pdu, &eod, sizeof(eod)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(END_OF_DATA)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &eod, sizeof(eod)) == -1) + goto badlen; if (rtr_check_session_id(rs, rs->session_id, &eod.hdr, pdu) == -1) return -1; if (rs->state != RTR_STATE_EXCHANGE) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(END_OF_DATA)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(END_OF_DATA)); return -1; } @@ -836,6 +811,11 @@ rtr_parse_end_of_data_v0(struct rtr_session *rs, struct ibuf *pdu) rtr_fsm(rs, RTR_EVNT_END_OF_DATA); return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(END_OF_DATA)); + return -1; } static int @@ -848,20 +828,15 @@ rtr_parse_end_of_data(struct rtr_session *rs, struct ibuf *pdu) if (rs->version == 0) return rtr_parse_end_of_data_v0(rs, pdu); - if (ibuf_get(pdu, &eod, sizeof(eod)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(END_OF_DATA)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &eod, sizeof(eod)) == -1) + goto badlen; if (rtr_check_session_id(rs, rs->session_id, &eod.hdr, pdu) == -1) return -1; if (rs->state != RTR_STATE_EXCHANGE) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(END_OF_DATA)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(END_OF_DATA)); return -1; } @@ -886,9 +861,13 @@ rtr_parse_end_of_data(struct rtr_session *rs, struct ibuf *pdu) return 0; bad: - log_warnx("rtr %s: received %s: bad timeout values", - log_rtr(rs), log_rtr_type(END_OF_DATA)); - rtr_send_error(rs, CORRUPT_DATA, "bad timeout values", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad timeout values", + log_rtr_type(END_OF_DATA)); + return -1; + +badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(END_OF_DATA)); return -1; } @@ -897,25 +876,25 @@ rtr_parse_cache_reset(struct rtr_session *rs, struct ibuf *pdu) { struct rtr_reset reset; - if (ibuf_get(pdu, &reset, sizeof(reset)) == -1) { - log_warnx("rtr %s: received %s: bad pdu length", - log_rtr(rs), log_rtr_type(CACHE_RESET)); - rtr_send_error(rs, CORRUPT_DATA, "bad length", pdu); - return -1; - } + if (ibuf_get(pdu, &reset, sizeof(reset)) == -1) + goto badlen; if (rtr_check_session_id(rs, 0, &reset.hdr, pdu) == -1) return -1; if (rs->state != RTR_STATE_ESTABLISHED) { - log_warnx("rtr %s: received %s: out of context", - log_rtr(rs), log_rtr_type(CACHE_RESET)); - rtr_send_error(rs, CORRUPT_DATA, "out of context", pdu); + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: out of context", + log_rtr_type(CACHE_RESET)); return -1; } rtr_fsm(rs, RTR_EVNT_CACHE_RESET); return 0; + + badlen: + rtr_send_error(rs, pdu, CORRUPT_DATA, "%s: bad length", + log_rtr_type(CACHE_RESET)); + return -1; } static char * @@ -1062,9 +1041,9 @@ rtr_process_msg(struct rtr_session *rs) return; break; default: - log_warnx("rtr %s: received %s: unsupported pdu type", - log_rtr(rs), log_rtr_type(msgtype)); - rtr_send_error(rs, UNSUPP_PDU_TYPE, NULL, &msg); + /* unreachable, checked in rtr_parse_header() */ + rtr_send_error(rs, &msg, UNSUPP_PDU_TYPE, "type %s", + log_rtr_type(msgtype)); return; } } @@ -1093,10 +1072,8 @@ rtr_fsm(struct rtr_session *rs, enum rtr_event event) * highest version number. */ rs->version = RTR_MAX_VERSION; - log_warnx("rtr %s: version negotiation failed", - log_rtr(rs)); - rtr_send_error(rs, UNSUPP_PROTOCOL_VERS, - NULL, NULL); + rtr_send_error(rs, NULL, UNSUPP_PROTOCOL_VERS, + "negotiation failed"); return; } -- 2.20.1