Skip to content

Commit

Permalink
Add external price as Babel metric
Browse files Browse the repository at this point in the history
This adds a uint value to the end of route updates that is propogated and
used as an external price metric so that it is possible to compute an amount
to be paid to traverse any given route based on whatever the asking price
of the intermediate notes
  • Loading branch information
jkilpatr committed Sep 11, 2017
1 parent d9390d1 commit 4e88ef5
Show file tree
Hide file tree
Showing 11 changed files with 144 additions and 32 deletions.
27 changes: 22 additions & 5 deletions babeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,11 @@ static int accept_local_connections(void);
static void init_signals(void);
static void dump_tables(FILE *out);

// The cost to retransmit using this node
unsigned int per_byte_cost = 0;
// Multiplier to indicate how much the user values funds vs quality
unsigned short price_multiplier = 1;

static int
kernel_route_notify(struct kernel_route *route, void *closure)
{
Expand Down Expand Up @@ -172,7 +177,7 @@ main(int argc, char **argv)

while(1) {
opt = getopt(argc, argv,
"m:p:h:H:i:k:A:sruS:d:g:G:lwz:M:t:T:c:C:DL:I:V");
"m:p:P:h:H:i:k:A:sruS:d:g:G:lwz:M:a:t:T:c:C:DL:I:V");
if(opt < 0)
break;

Expand All @@ -197,6 +202,9 @@ main(int argc, char **argv)
if(protocol_port <= 0 || protocol_port > 0xFFFF)
goto usage;
break;
case 'P':
per_byte_cost = parse_price(optarg);
break;
case 'h':
default_wireless_hello_interval = parse_thousands(optarg);
if(default_wireless_hello_interval <= 0 ||
Expand Down Expand Up @@ -281,6 +289,11 @@ main(int argc, char **argv)
change_smoothing_half_life(l);
break;
}
case 'a': {
//Adjust price sensitivity
price_multiplier = parse_price(optarg);
break;
}
case 't':
export_table = parse_nat(optarg);
if(export_table < 0 || export_table > 0xFFFF)
Expand Down Expand Up @@ -1074,13 +1087,16 @@ dump_route(FILE *out, struct babel_route *route)
snprintf(channels + j, 100 - j, ")");
}

fprintf(out, "%s%s%s metric %d (%d) refmetric %d id %s "
fprintf(out, "%s%s%s metric %d (%d) price %d refmetric %d id %s "
"seqno %d%s age %d via %s neigh %s%s%s%s\n",
format_prefix(route->src->prefix, route->src->plen),
route->src->src_plen > 0 ? " from " : "",
route->src->src_plen > 0 ?
format_prefix(route->src->src_prefix, route->src->src_plen) : "",
route_metric(route), route_smoothed_metric(route), route->refmetric,
route_metric(route),
route_smoothed_metric(route),
route->price,
route->refmetric,
format_eui64(route->src->id),
(int)route->seqno,
channels,
Expand All @@ -1096,12 +1112,13 @@ dump_route(FILE *out, struct babel_route *route)
static void
dump_xroute(FILE *out, struct xroute *xroute)
{
fprintf(out, "%s%s%s metric %d (exported)\n",
fprintf(out, "%s%s%s metric %d price %d (exported)\n",
format_prefix(xroute->prefix, xroute->plen),
xroute->src_plen > 0 ? " from " : "",
xroute->src_plen > 0 ?
format_prefix(xroute->src_prefix, xroute->src_plen) : "",
xroute->metric);
xroute->metric,
xroute->price);
}

static void
Expand Down
3 changes: 3 additions & 0 deletions babeld.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ extern int protocol_socket;
extern int kernel_socket;
extern int max_request_hopcount;

extern unsigned int per_byte_cost;
extern unsigned short price_multiplier;

void schedule_neighbours_check(int msecs, int override);
void schedule_interfaces_check(int msecs, int override);
int resize_receive_buffer(int size);
Expand Down
31 changes: 29 additions & 2 deletions configuration.c
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ THE SOFTWARE.
#include "interface.h"
#include "route.h"
#include "kernel.h"
#include "xroute.h"
#include "configuration.h"
#include "rule.h"

Expand Down Expand Up @@ -169,6 +170,24 @@ getint(int c, int *int_r, gnc_t gnc, void *closure)
return c;
}

static unsigned int
getuint(int c, unsigned int *int_r, gnc_t gnc, void *closure)
{
char *t, *end;
unsigned int i;
c = getword(c, &t, gnc, closure);
if(c < -1)
return c;
i = strtoul(t, &end, 0);
if(*end != '\0') {
free(t);
return -2;
}
free(t);
*int_r = i;
return c;
}

static int
getthousands(int c, int *int_r, gnc_t gnc, void *closure)
{
Expand Down Expand Up @@ -760,8 +779,9 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
strcmp(token, "log-file") != 0 &&
strcmp(token, "diversity") != 0 &&
strcmp(token, "diversity-factor") != 0 &&
strcmp(token, "smoothing-half-life") != 0)
goto error;
strcmp(token, "smoothing-half-life") != 0 &&
strcmp(token, "price") != 0)
goto error;
}

if(strcmp(token, "protocol-port") == 0 ||
Expand Down Expand Up @@ -889,6 +909,13 @@ parse_option(int c, gnc_t gnc, void *closure, char *token)
if(c < -1 || f < 0 || f > 256)
goto error;
diversity_factor = f;
} else if(strcmp(token, "price") == 0) {
unsigned int f = 0;
c = getuint(c, &f, gnc, closure);
if(c < -1 || f > 4294967295)
goto error;
per_byte_cost = f;
check_xroutes(1);
} else if(strcmp(token, "smoothing-half-life") == 0) {
int h;
c = getint(c, &h, gnc, closure);
Expand Down
27 changes: 25 additions & 2 deletions local.c
Original file line number Diff line number Diff line change
Expand Up @@ -238,13 +238,14 @@ local_notify_route_1(struct local_socket *s, struct babel_route *route, int kind

rc = snprintf(buf, 512,
"%s route %lx prefix %s from %s installed %s "
"id %s metric %d refmetric %d via %s if %s\n",
"id %s metric %d price %u refmetric %d via %s if %s\n",
local_kind(kind),
(unsigned long)route,
dst_prefix, src_prefix,
route->installed ? "yes" : "no",
format_eui64(route->src->id),
route_metric(route), route->refmetric,
route_metric(route), route->price,
route->refmetric,
format_address(route->neigh->address),
route->neigh->ifp->name);

Expand All @@ -271,6 +272,26 @@ local_notify_route(struct babel_route *route, int kind)
}
}

static void
local_notify_price_1(struct local_socket *s)
{
char buf[64];
int rc;
rc = snprintf(buf, 64, "local price %d\n", per_byte_cost);

if(rc < 0 || rc >= 64)
goto fail;

rc = write_timeout(s->fd, buf, rc);
if(rc < 0)
goto fail;
return;

fail:
shutdown(s->fd, 1);
return;
}

static void
local_notify_all_1(struct local_socket *s)
{
Expand All @@ -279,6 +300,8 @@ local_notify_all_1(struct local_socket *s)
struct xroute_stream *xroutes;
struct route_stream *routes;

local_notify_price_1(s);

FOR_ALL_INTERFACES(ifp) {
local_notify_interface_1(s, ifp, LOCAL_ADD);
}
Expand Down
32 changes: 19 additions & 13 deletions message.c
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
unsigned char channels[MAX_CHANNEL_HOPS];
int channels_len = MAX_CHANNEL_HOPS;
unsigned short interval, seqno, metric;
unsigned int price;
int rc, parsed_len;
if(len < 10) {
if(len < 2 || message[3] & 0x80)
Expand All @@ -477,10 +478,11 @@ parse_packet(const unsigned char *from, struct interface *ifp,
DO_NTOHS(interval, message + 6);
DO_NTOHS(seqno, message + 8);
DO_NTOHS(metric, message + 10);
DO_NTOHL(price, message + 12);
if(message[5] == 0 ||
(message[2] == 1 ? have_v4_prefix : have_v6_prefix))
rc = network_prefix(message[2], message[4], message[5],
message + 12,
message + 16,
message[2] == 1 ? v4_prefix : v6_prefix,
len - 10, prefix);
else
Expand All @@ -497,7 +499,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
have_v4_prefix = have_v6_prefix = 0;
goto fail;
}
parsed_len = 10 + rc;
parsed_len = 16 + rc;

plen = message[4] + (message[2] == 1 ? 96 : 0);

Expand Down Expand Up @@ -555,7 +557,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
parse_update_subtlv(ifp, metric, message + 2 + parsed_len,
len - parsed_len, channels, &channels_len);
update_route(router_id, prefix, plen, src_prefix, src_plen, seqno,
metric, interval, neigh, nh,
metric, interval, price, neigh, nh,
channels, channels_len);
} else if(type == MESSAGE_REQUEST) {
unsigned char prefix[16], src_prefix[16], plen, src_plen;
Expand Down Expand Up @@ -619,6 +621,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
unsigned char channels[MAX_CHANNEL_HOPS];
int channels_len = MAX_CHANNEL_HOPS;
unsigned short interval, seqno, metric;
unsigned int price;
const unsigned char *src_prefix_beginning = NULL;
int rc, parsed_len = 0;
if(len < 10)
Expand All @@ -630,16 +633,17 @@ parse_packet(const unsigned char *from, struct interface *ifp,
DO_NTOHS(interval, message + 6);
DO_NTOHS(seqno, message + 8);
DO_NTOHS(metric, message + 10);
DO_NTOHL(price, message + 12);
if(omitted == 0 || (ae == 1 ? have_v4_prefix : have_v6_prefix))
rc = network_prefix(ae, plen, omitted, message + 12,
rc = network_prefix(ae, plen, omitted, message + 16,
ae == 1 ? v4_prefix : v6_prefix,
len - 10, prefix);
else
rc = -1;
if(rc < 0)
goto fail;

parsed_len = 10 + rc;
parsed_len = 16 + rc;
src_prefix_beginning = message + 2 + parsed_len;

rc = network_prefix(ae, src_plen, 0, src_prefix_beginning, NULL,
Expand Down Expand Up @@ -683,7 +687,7 @@ parse_packet(const unsigned char *from, struct interface *ifp,
parse_update_subtlv(ifp, metric, message + 2 + parsed_len,
len - parsed_len, channels, &channels_len);
update_route(router_id, prefix, plen, src_prefix, src_plen,
seqno, metric, interval, neigh, nh,
seqno, metric, interval, price, neigh, nh,
channels, channels_len);
} else if(type == MESSAGE_REQUEST_SRC_SPECIFIC) {
unsigned char prefix[16], plen, ae, src_prefix[16], src_plen;
Expand Down Expand Up @@ -1154,6 +1158,7 @@ really_send_update(struct interface *ifp,
const unsigned char *prefix, unsigned char plen,
const unsigned char *src_prefix, unsigned char src_plen,
unsigned short seqno, unsigned short metric,
unsigned int price,
unsigned char *channels, int channels_len)
{
int add_metric, v4, real_plen, omit = 0;
Expand Down Expand Up @@ -1230,11 +1235,11 @@ really_send_update(struct interface *ifp,
}

if(!is_ss)
start_message(ifp, MESSAGE_UPDATE, 10 + (real_plen + 7) / 8 - omit +
start_message(ifp, MESSAGE_UPDATE, 14 + (real_plen + 7) / 8 - omit +
channels_size);
else
start_message(ifp, MESSAGE_UPDATE_SRC_SPECIFIC,
10 + (real_plen + 7) / 8 - omit +
14 + (real_plen + 7) / 8 - omit +
(real_src_plen + 7) / 8 + channels_size);
accumulate_byte(ifp, v4 ? 1 : 2);
if(is_ss)
Expand All @@ -1246,6 +1251,7 @@ really_send_update(struct interface *ifp,
accumulate_short(ifp, (ifp->update_interval + 5) / 10);
accumulate_short(ifp, seqno);
accumulate_short(ifp, metric);
accumulate_int(ifp, price);
accumulate_bytes(ifp, real_prefix + omit, (real_plen + 7) / 8 - omit);
if(is_ss)
accumulate_bytes(ifp, real_src_prefix, (real_src_plen + 7) / 8);
Expand All @@ -1256,11 +1262,11 @@ really_send_update(struct interface *ifp,
accumulate_bytes(ifp, channels, channels_len);
}
if(!is_ss)
end_message(ifp, MESSAGE_UPDATE, 10 + (real_plen + 7) / 8 - omit +
end_message(ifp, MESSAGE_UPDATE, 14 + (real_plen + 7) / 8 - omit +
channels_size);
else
end_message(ifp, MESSAGE_UPDATE_SRC_SPECIFIC,
10 + (real_plen + 7) / 8 - omit +
14 + (real_plen + 7) / 8 - omit +
(real_src_plen + 7) / 8 + channels_size);

if(flags & 0x80) {
Expand Down Expand Up @@ -1379,7 +1385,7 @@ flushupdates(struct interface *ifp)
really_send_update(ifp, myid,
xroute->prefix, xroute->plen,
xroute->src_prefix, xroute->src_plen,
myseqno, xroute->metric,
myseqno, xroute->metric, xroute->price,
NULL, 0);
last_prefix = xroute->prefix;
last_plen = xroute->plen;
Expand Down Expand Up @@ -1428,7 +1434,7 @@ flushupdates(struct interface *ifp)
really_send_update(ifp, route->src->id,
route->src->prefix, route->src->plen,
route->src->src_prefix, route->src->src_plen,
seqno, metric,
seqno, metric, route->price,
channels, chlen);
update_source(route->src, seqno, metric);
last_prefix = route->src->prefix;
Expand All @@ -1440,7 +1446,7 @@ flushupdates(struct interface *ifp)
after an xroute has been retracted, so send a retraction. */
really_send_update(ifp, myid, b[i].prefix, b[i].plen,
b[i].src_prefix, b[i].src_plen,
myseqno, INFINITY, NULL, -1);
myseqno, INFINITY, INFINITY ,NULL, -1);
}
}
schedule_flush_now(ifp);
Expand Down
Loading

0 comments on commit 4e88ef5

Please sign in to comment.