+/*
+ * Copyright (c) 2016, JANET(UK)
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of JANET(UK) nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
#include <fcntl.h>
#include <talloc.h>
#include <errno.h>
tr_debug("trps_handle_connection: connection closed.");
}
+/* TODO: check realm/comm, now part of the update instead of inforec */
static TRP_RC trps_validate_update(TRPS_INSTANCE *trps, TRP_UPD *upd)
{
if (upd==NULL) {
return TRP_BADARG;
}
+ if (trp_upd_get_realm(upd)==NULL) {
+ tr_notice("trps_validate_update: received TRP update without realm.");
+ return TRP_ERROR;
+ }
+
+ if (trp_upd_get_comm(upd)==NULL) {
+ tr_notice("trps_validate_update: received TRP update without community.");
+ return TRP_ERROR;
+ }
+
if (trp_upd_get_inforec(upd)==NULL) {
tr_notice("trps_validate_update: received TRP update with no info records.");
return TRP_ERROR;
tr_notice("trps_validate_update: received TRP update without origin peer information.");
return TRP_ERROR;
}
+
return TRP_SUCCESS;
}
{
switch(trp_inforec_get_type(rec)) {
case TRP_INFOREC_TYPE_ROUTE:
- if ((trp_inforec_get_comm(rec)==NULL)
- || (trp_inforec_get_realm(rec)==NULL)
- || (trp_inforec_get_trust_router(rec)==NULL)
+ if ((trp_inforec_get_trust_router(rec)==NULL)
|| (trp_inforec_get_next_hop(rec)==NULL)) {
tr_debug("trps_validate_inforec: missing record info.");
return TRP_ERROR;
return trp_route_get_metric(entry) + trps_cost(trps, peer);
}
-static int trps_check_feasibility(TRPS_INSTANCE *trps, TRP_INFOREC *rec)
+static int trps_check_feasibility(TRPS_INSTANCE *trps, TR_NAME *realm, TR_NAME *comm, TRP_INFOREC *rec)
{
unsigned int rec_metric=trp_inforec_get_metric(rec);
unsigned int new_metric=0;
return 1;
/* updates from our current next hop are always feasible*/
- next_hop=trps_get_next_hop(trps,
- trp_inforec_get_comm(rec),
- trp_inforec_get_realm(rec));;
+ next_hop=trps_get_next_hop(trps, comm, realm);
if ((next_hop!=NULL)
&& (0==tr_name_cmp(next_hop,trp_inforec_get_next_hop(rec)))) {
return 1;
/* compare the existing metric we advertise to what we would advertise
* if we accept this update */
- current_metric=trps_advertised_metric(trps,
- trp_inforec_get_comm(rec),
- trp_inforec_get_realm(rec),
- trp_inforec_get_next_hop(rec));
+ current_metric=trps_advertised_metric(trps, comm, realm, trp_inforec_get_next_hop(rec));
new_metric=rec_metric + trps_cost(trps, trp_inforec_get_next_hop(rec));
if (new_metric <= current_metric)
return 1;
TRP_ROUTE *entry=NULL;
entry=trp_rtable_get_entry(trps->rtable,
- trp_inforec_get_comm(rec),
- trp_inforec_get_realm(rec),
+ trp_upd_get_comm(upd),
+ trp_upd_get_realm(upd),
trp_inforec_get_next_hop(rec));
if (entry==NULL) {
entry=trp_route_new(NULL);
return TRP_NOMEM;
}
- trp_route_set_comm(entry, trp_inforec_dup_comm(rec));
- trp_route_set_realm(entry, trp_inforec_dup_realm(rec));
+ trp_route_set_comm(entry, trp_upd_dup_comm(upd));
+ trp_route_set_realm(entry, trp_upd_dup_realm(upd));
trp_route_set_peer(entry, trp_upd_dup_peer(upd));
trp_route_set_trust_router(entry, trp_inforec_dup_trust_router(rec));
trp_route_set_next_hop(entry, trp_inforec_dup_next_hop(rec));
for (rec=trp_upd_get_inforec(upd); rec!=NULL; rec=trp_inforec_get_next(rec)) {
/* determine feasibility */
- feas=trps_check_feasibility(trps, rec);
+ feas=trps_check_feasibility(trps, trp_upd_get_realm(upd), trp_upd_get_comm(upd), rec);
tr_debug("trps_handle_update: record feasibility=%d", feas);
/* do we have an existing route? */
route=trps_get_route(trps,
- trp_inforec_get_comm(rec),
- trp_inforec_get_realm(rec),
+ trp_upd_get_comm(upd),
+ trp_upd_get_realm(upd),
trp_upd_get_peer(upd));
if (route!=NULL) {
/* there was a route table entry already */
/* Note that we leave the next hop empty since the recipient fills that in.
* This is where we add the link cost (currently always 1) to the next peer. */
- if ((trp_inforec_set_comm(rec, trp_route_dup_comm(route)) != TRP_SUCCESS)
- ||(trp_inforec_set_realm(rec, trp_route_dup_realm(route)) != TRP_SUCCESS)
- ||(trp_inforec_set_trust_router(rec, trp_route_dup_trust_router(route)) != TRP_SUCCESS)
+ if ((trp_inforec_set_trust_router(rec, trp_route_dup_trust_router(route)) != TRP_SUCCESS)
||(trp_inforec_set_metric(rec,
trps_metric_add(trp_route_get_metric(route),
linkcost)) != TRP_SUCCESS)
tr_debug("trps_update_one_peer: sending %u update records.", (unsigned int)n_updates);
upd=trp_upd_new(tmp_ctx);
+ /* TODO: set realm/comm in update; used to be in the inforec */
for (ii=0; ii<n_updates; ii++) {
rec=trps_route_to_inforec(tmp_ctx, trps, update_list[ii]);
if (rec==NULL) {
encoded=NULL;
trp_upd_free(upd);
upd=NULL;
- }
+ } else if (n_updates==0)
+ tr_debug("trps_update_one_peer: no updates for %.*s", peer_label->len, peer_label->buf);
+
+ rc=TRP_SUCCESS;
cleanup:
talloc_free(tmp_ctx);
}
rc=trps_update_one_peer(trps, peer, update_type, NULL, NULL);
}
-
+
+ tr_debug("trps_update: rc=%u after attempting update.", rc);
trp_ptable_iter_free(iter);
trp_rtable_clear_triggered(trps->rtable); /* don't re-send triggered updates */
talloc_free(tmp_ctx);