+/* add metrics */
+static unsigned int trps_metric_add(unsigned int m1, unsigned int m2)
+{
+ if (trp_metric_is_invalid(m1) || trp_metric_is_invalid(m2))
+ return TRP_METRIC_INVALID;
+
+ if (trp_metric_is_infinite(m1) || trp_metric_is_infinite(m2))
+ return TRP_METRIC_INFINITY;
+
+ if (trp_metric_is_finite(m1+m2))
+ return m1+m2;
+ else
+ return TRP_METRIC_INFINITY;
+}
+
+/* convert an rentry into a new trp update info record */
+static TRP_INFOREC *trps_route_to_inforec(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *trps, TRP_ROUTE *route)
+{
+ TRP_INFOREC *rec=trp_inforec_new(mem_ctx, TRP_INFOREC_TYPE_ROUTE);
+ unsigned int linkcost=0;
+
+ if (rec!=NULL) {
+ if (trp_route_is_local(route))
+ linkcost=0;
+ else {
+ linkcost=trp_peer_get_linkcost(trps_get_peer_by_gssname(trps,
+ trp_route_get_peer(route)));
+ }
+
+ /* 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_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)
+ ||(trp_inforec_set_interval(rec, trps_get_update_interval(trps)) != TRP_SUCCESS)) {
+ tr_err("trps_route_to_inforec: error creating route update.");
+ talloc_free(rec);
+ rec=NULL;
+ }
+ }
+ return rec;
+}
+
+static TRP_UPD *trps_route_to_upd(TALLOC_CTX *mem_ctx, TRPS_INSTANCE *trps, TRP_ROUTE *route)
+{
+ TALLOC_CTX *tmp_ctx=talloc_new(NULL);
+ TRP_UPD *upd=trp_upd_new(tmp_ctx);
+ TRP_INFOREC *rec=NULL;
+
+ if (upd==NULL) {
+ tr_err("trps_route_to_upd: could not create update message.");
+ goto cleanup;
+ }
+ trp_upd_set_realm(upd, trp_route_dup_realm(route));
+ if (trp_upd_get_realm(upd)==NULL) {
+ tr_err("trps_route_to_upd: could not copy realm.");
+ upd=NULL; /* it's still in tmp_ctx, so it will be freed */
+ goto cleanup;
+ }
+ trp_upd_set_comm(upd, trp_route_dup_comm(route));
+ if (trp_upd_get_comm(upd)==NULL) {
+ tr_err("trps_route_to_upd: could not copy comm.");
+ upd=NULL; /* it's still in tmp_ctx, so it will be freed */
+ goto cleanup;
+ }
+ rec=trps_route_to_inforec(tmp_ctx, trps, route);
+ if (rec==NULL) {
+ tr_err("trps_route_to_upd: could not create route info record for realm %.*s in comm %.*s.",
+ trp_route_get_realm(route)->len, trp_route_get_realm(route)->buf,
+ trp_route_get_comm(route)->len, trp_route_get_comm(route)->buf);
+ upd=NULL; /* it's till in tmp_ctx, so it will be freed */
+ goto cleanup;
+ }
+ trp_upd_add_inforec(upd, rec);
+
+ /* sucess */
+ talloc_steal(mem_ctx, upd);
+
+cleanup:
+ talloc_free(tmp_ctx);
+ return upd;
+}
+