return err_pdu_send_internal_error(stream.fd, stream.ver);
}
+struct withdrawal {
+ unsigned char raw[22];
+};
+
+struct withdrawal_array {
+ struct withdrawal *a; /* array */
+ size_t n; /* array length */
+ size_t c; /* array capacity */
+};
+
+static void
+add_withdrawal(struct withdrawal_array *wds, unsigned char const *chunk, size_t size)
+{
+ if (wds->n >= wds->c) {
+ wds->c <<= 1;
+ wds->a = prealloc(wds->a, wds->c * sizeof(struct withdrawal));
+ }
+ memcpy(wds->a[wds->n++].raw, chunk, size);
+}
+
static int
-send_delta(struct rtr_stream *rs, serial_t oserial, serial_t nserial)
+send_pfx_delta(struct rtr_stream *rs, serial_t oserial, serial_t nserial)
{
FILE *ofile = NULL;
FILE *nfile = NULL;
unsigned char *buf2;
unsigned char const *ochunk;
unsigned char const *nchunk;
+ struct withdrawal_array wds;
+ ssize_t w;
int cmp;
int error;
buf1 = pmalloc(rs->rawlen);
buf2 = pmalloc(rs->rawlen);
+ wds.n = 0;
+ wds.c = 128;
+ wds.a = pmalloc(wds.c * sizeof(struct withdrawal));
+
error = rtr_open_file(oserial, rs->type, "r", &ofile);
if (error)
goto end;
while (ochunk && nchunk) {
cmp = memcmp(ochunk, nchunk, rs->rawlen);
- if (cmp < 0) {
- error = rs->send(rs, ochunk, FLAG_WITHDRAWAL);
- if (error)
- goto end;
+ if (cmp > 0) {
+ add_withdrawal(&wds, ochunk, rs->rawlen);
ochunk = next_chunk(ofile, buf1, rs->rawlen, &error);
if (error)
goto end;
- } else if (cmp > 0) {
+ } else if (cmp < 0) {
error = rs->send(rs, nchunk, FLAG_ANNOUNCEMENT);
if (error)
goto end;
}
}
- while (ochunk) {
- error = rs->send(rs, ochunk, FLAG_WITHDRAWAL);
+ while (nchunk) {
+ error = rs->send(rs, nchunk, FLAG_ANNOUNCEMENT);
if (error)
goto end;
- ochunk = next_chunk(ofile, buf1, rs->rawlen, &error);
+ nchunk = next_chunk(nfile, buf2, rs->rawlen, &error);
if (error)
goto end;
}
- while (nchunk) {
- error = rs->send(rs, nchunk, FLAG_ANNOUNCEMENT);
+ while (ochunk) {
+ add_withdrawal(&wds, ochunk, rs->rawlen);
+ ochunk = next_chunk(ofile, buf1, rs->rawlen, &error);
if (error)
goto end;
- nchunk = next_chunk(nfile, buf2, rs->rawlen, &error);
+ }
+
+ for (w = wds.n - 1; w >= 0; w--) {
+ error = rs->send(rs, wds.a[w].raw, FLAG_WITHDRAWAL);
if (error)
goto end;
}
end: if (nfile) fclose(nfile);
if (ofile) fclose(ofile);
+ free(wds.a);
free(buf2);
free(buf1);
return error;
}
static int
-send_aspa_delta(int fd, uint8_t ver, serial_t oserial, serial_t nserial)
+send_aspa_delta(int fd, uint8_t ver, serial_t oserial, serial_t nserial,
+ bool announce)
{
FILE *ofile = NULL;
FILE *nfile = NULL;
while (ochunk && nchunk) {
cmp = memcmp(ochunk, nchunk, 4); /* AS only */
if (cmp < 0) {
- error = send_aspa_withdraw(fd, ver, ochunk, ofile);
+ error = announce
+ ? skip_providers(ochunk, ofile)
+ : send_aspa_withdraw(fd, ver, ochunk, ofile);
if (error)
goto end;
ochunk = next_chunk(ofile, buf1, 8, &error);
if (error)
goto end;
} else if (cmp > 0) {
- error = send_aspa_announce(fd, ver, nchunk, nfile);
+ error = announce
+ ? send_aspa_announce(fd, ver, nchunk, nfile)
+ : skip_providers(nchunk, nfile);
if (error)
goto end;
nchunk = next_chunk(nfile, buf2, 8, &error);
goto end;
}
- if (!providers_equal(&oprovs, &nprovs)) {
+ if (announce && !providers_equal(&oprovs, &nprovs)) {
aspa.customer = read_u32(nchunk);
aspa.providers = nprovs;
error = send_aspa_announce_pdu(fd, ver, &aspa);
}
}
- while (ochunk) {
- error = send_aspa_withdraw(fd, ver, ochunk, ofile);
- if (error)
- goto end;
- ochunk = next_chunk(ofile, buf1, 8, &error);
- if (error)
- goto end;
- }
-
- while (nchunk) {
- error = send_aspa_announce(fd, ver, nchunk, nfile);
- if (error)
- goto end;
- nchunk = next_chunk(nfile, buf2, 8, &error);
- if (error)
- goto end;
+ if (announce) {
+ while (nchunk) {
+ error = send_aspa_announce(fd, ver, nchunk, nfile);
+ if (error)
+ goto end;
+ nchunk = next_chunk(nfile, buf2, 8, &error);
+ if (error)
+ goto end;
+ }
+ } else {
+ while (ochunk) {
+ error = send_aspa_withdraw(fd, ver, ochunk, ofile);
+ if (error)
+ goto end;
+ ochunk = next_chunk(ofile, buf1, 8, &error);
+ if (error)
+ goto end;
+ }
}
end: if (ofile) fclose(ofile);
stream.type = "vrp4";
stream.rawlen = 10;
stream.send = send_vrp4;
- error = send_delta(&stream, oserial, nserial);
+ error = send_pfx_delta(&stream, oserial, nserial);
if (error)
goto internal_error;
stream.type = "vrp6";
stream.rawlen = 22;
stream.send = send_vrp6;
- error = send_delta(&stream, oserial, nserial);
+ error = send_pfx_delta(&stream, oserial, nserial);
if (error)
goto internal_error;
+ /*
if (stream.ver >= RTR_V1) {
stream.type = "rk";
stream.rawlen = 4 + RK_SKI_LEN + RK_SPKI_LEN;
if (error)
goto internal_error;
}
+ */
if (stream.ver >= RTR_V2) {
- error = send_aspa_delta(stream.fd, stream.ver, oserial, nserial);
+ error = send_aspa_delta(stream.fd, stream.ver, oserial, nserial,
+ true);
+ if (error)
+ goto internal_error;
+ error = send_aspa_delta(stream.fd, stream.ver, oserial, nserial,
+ false);
if (error)
goto internal_error;
}
pr_op_debug("Expected:");
for (i = 0; i < e; i++)
- pr_op_debug("- %s %u %u", pdutype2str(expected[i].type),
- expected[i].as, expected[i].flags);
+ pr_op_debug("%s %s as:%u", expected[i].flags ? "+" : "-",
+ pdutype2str(expected[i].type), expected[i].as);
pr_op_debug("Actual:");
for (i = 0; i < a; i++)
- pr_op_debug("- %s %u %u", pdutype2str(actual[i].type),
- actual[i].as, actual[i].flags);
+ pr_op_debug("%s %s as:%u", expected[i].flags ? "+" : "-",
+ pdutype2str(actual[i].type), actual[i].as);
ck_assert_uint_eq(e, a);
for (i = 0; i < e; i++) {
e = 0;
expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0);
- expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_ANNOUNCEMENT);
- expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT);
+ expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_ANNOUNCEMENT);
+ expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0);
expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_ANNOUNCEMENT);
- expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT);
+// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0);
rcv_serial_query(session, 1);
e = 0;
expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0);
- expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_ANNOUNCEMENT);
- expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_WITHDRAWAL);
+ expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_ANNOUNCEMENT);
- expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL);
- expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT);
- expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_WITHDRAWAL);
+ expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_WITHDRAWAL);
+// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT);
+// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_ANNOUNCEMENT);
+ expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0);
rcv_serial_query(session, 1);
expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0);
expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_WITHDRAWAL);
- expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL);
+// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0);
rcv_serial_query(session, 2);
expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0);
expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_WITHDRAWAL);
- expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL);
+// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0);
rcv_serial_query(session, 2);
expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_WITHDRAWAL);
- expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT);
- expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL);
+// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT);
+// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0);
e = 0;
expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0);
- expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_ANNOUNCEMENT);
- expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT);
+ expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_ANNOUNCEMENT);
+ expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0);
expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_ANNOUNCEMENT);
- expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT);
+// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0);
rcv_serial_query(session, 1);
expected_pdu_add(PDU_TYPE_CACHE_RESPONSE, 0, 0);
expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 1, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_WITHDRAWAL);
- expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL);
+// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0);
rcv_serial_query(session, 2);
expected_pdu_add(PDU_TYPE_IPV4_PREFIX, 2, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_IPV6_PREFIX, 2, FLAG_WITHDRAWAL);
- expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT);
- expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL);
+// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 1, FLAG_ANNOUNCEMENT);
+// expected_pdu_add(PDU_TYPE_ROUTER_KEY, 2, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_ASPA, 1, FLAG_ANNOUNCEMENT);
expected_pdu_add(PDU_TYPE_ASPA, 2, FLAG_WITHDRAWAL);
expected_pdu_add(PDU_TYPE_END_OF_DATA, 0, 0);