buffer (buffer closure): buffer for incoming packets
authbind (string): optional, path to authbind-helper program
max-interfaces (number): optional, max number of different interfaces to
- use (also, maximum steady-state amount of packet multiplication)
+ use (also, maximum steady-state amount of packet multiplication);
+ interfaces marked with `@' do not count.
interfaces (string list): which interfaces to process; each entry is
- optionally `!' or `+' followed by a glob pattern (which is applied to a
- prospective interface using fnmatch with no flags). If no list is
- specified, or the list ends with a `!' entry, a default list is
- used/appended: "!tun*","!tap*","!sl*","!userv*","!lo","*". Patterns
- which do not start with `*' or an alphanumeric need to be preceded
- by `!' or `+'.
+ optionally `!' or `+' or `@' followed by a glob pattern (which is
+ applied to a prospective interface using fnmatch with no flags).
+ `+' or nothing means to process normally. `!' means to ignore;
+ `@' means to use only in conjunction with dedicated-interface-addr.
+ If no list is specified, or the list ends with a `!' entry, a
+ default list is used/appended:
+ "!tun*","!tap*","!sl*","!userv*","!lo","@hippo*","*".
+ Patterns which do not start with `*' or an alphanumeric need to be
+ preceded by `!' or `+' or `@'.
monitor-command (string list): Program to use to monitor appearance
and disappearance of addresses on local network interfaces. Should
produce lines of the form `+|-<ifname> 4|6 <addr>' where <addr> is
mobile the address selection machinery might fixate on an unsuitable
address.
+polypath takes site-specific informtion as passed to the `comm-info'
+site closure parameter. The entries understood in the dictionary
+are:
+ dedicated-interface-addr (string): IPv4 or IPv6 address
+ literal. Interfaces specified with `@' in `interfaces' will be
+ used for the corresponding site iff the interface local address
+ is this address.
+
For an interface to work with polypath, it must either have a suitable
default route, or be a point-to-point interface. In the general case
this might mean that the host would have to have multiple default
to 0, the default is to use the local private link mtu.
comm-info (dict): Information for the comm, used when this site
wants to transmit. If the comm does not support this, it is
- ignored. (Currently nothing uses this.)
+ ignored.
Links involving mobile peers have some different tuning parameter
default values, which are generally more aggressive about retrying key
const char *const *ifname_pats;
const char *const *monitor_command;
bool_t permit_loopback;
- LIST_HEAD(interf_list, interf) interfs;
+ LIST_HEAD(interf_list, interf) interfs_general;
+ struct interf_list interfs_dedicated;
struct buffer_if lbuf;
int monitor_fd;
pid_t monitor_pid;
int privsep_ipcsock_fd;
};
+struct comm_clientinfo {
+ union iaddr dedicated; /* might be AF_UNSPEC */
+};
+
static void polypath_phase_shutdown(void *sst, uint32_t newphase);
#define LG 0, st->uc.cc.cl.description, &st->uc.cc.loc
"!lo", 0
};
static const char *const default_ifname_pats[] = {
- "!tun*","!tap*","!sl*","!userv*", "*", 0
+ "!tun*","!tap*","!sl*","!userv*", "@hippo*", "*", 0
};
static const char *const default_monitor_command[] = {
abort();
}
+static struct comm_clientinfo *polypath_clientinfo(void *state,
+ dict_t *dict, struct cloc cloc) {
+ struct comm_clientinfo *clientinfo;
+
+ NEW(clientinfo);
+ FILLZERO(*clientinfo);
+ clientinfo->dedicated.sa.sa_family=AF_UNSPEC;
+
+ item_t *item = dict_find_item(dict,"dedicated-interface-addr",
+ False,"polypath",cloc);
+ if (item) string_item_to_iaddr(item,0,&clientinfo->dedicated,
+ "polypath");
+ return clientinfo;
+}
+
static int polypath_beforepoll(void *state, struct pollfd *fds, int *nfds_io,
int *timeout_io)
{
struct interf_list *interfs;
switch (want) {
- case '+': interfs=&st->interfs; max_interfs=st->max_interfs;
+ case '+': interfs=&st->interfs_general; max_interfs=st->max_interfs;
+ case '@': interfs=&st->interfs_dedicated; max_interfs=INT_MAX;
default: fatal("polypath: got bad want (%#x, %s)", want, ifname);
}
struct interf *interf,
struct buffer_if *buf,
const struct comm_addr *dest,
+ const union iaddr *dedicated,
bool_t *allreasonable)
{
int i;
int af=dest->ia.sa.sa_family;
- bool_t attempted=False, reasonable=False;
+ bool_t wanted=False, attempted=False, reasonable=False;
for (i=0; i<interf->socks.n_socks; i++) {
struct udpsock *us=&interf->socks.socks[i];
+ if (dedicated && !iaddr_equal(dedicated, &us->addr, True))
+ continue;
+ wanted=True;
if (af != us->addr.sa.sa_family)
continue;
attempted=True;
interf->name,iaddr_to_string(&us->addr),
buf->size,iaddr_to_string(&dest->ia));
}
+ if (!wanted)
+ return;
+
if (!attempted)
if (!interf->experienced_xmit_noaf[af]++)
lg_perror(LG,M_WARNING,0,
struct interf *interf;
bool_t allreasonable=True;
- LIST_FOREACH(interf,&st->interfs,entry) {
+ LIST_FOREACH(interf,&st->interfs_general,entry) {
polypath_sendmsg_interf(st,interf,buf,dest,
- &allreasonable);
+ 0, &allreasonable);
+ }
+ if (clientinfo && clientinfo->dedicated.sa.sa_family != AF_UNSPEC) {
+ LIST_FOREACH(interf,&st->interfs_dedicated,entry) {
+ polypath_sendmsg_interf(st,interf,buf,dest,
+ &clientinfo->dedicated, &allreasonable);
+ }
}
return allreasonable;
}
bool_t add;
char ifname[100];
union iaddr ia;
- char want; /* `+', for now */
+ char want; /* `+' or `@' */
};
static void papp_bad(struct polypath *st, void *badctx,
struct polypath *st=sst;
struct interf *interf;
- LIST_FOREACH(interf,&st->interfs,entry)
+ LIST_FOREACH(interf,&st->interfs_general,entry)
+ udp_socks_childpersist(&st->uc,&interf->socks);
+ LIST_FOREACH(interf,&st->interfs_dedicated,entry)
udp_socks_childpersist(&st->uc,&interf->socks);
}
COMM_APPLY_STANDARD(st,&st->uc.cc,"polypath",args);
UDP_APPLY_STANDARD(st,&st->uc,"polypath");
+ st->uc.cc.ops.clientinfo = polypath_clientinfo;
+
struct udpcommon *uc=&st->uc;
struct commcommon *cc=&uc->cc;
st->permit_loopback=dict_read_bool(d,"permit-loopback",False,
"polypath",cc->loc,False);
- LIST_INIT(&st->interfs);
+ LIST_INIT(&st->interfs_general);
+ LIST_INIT(&st->interfs_dedicated);
buffer_new(&st->lbuf,ADNS_ADDR2TEXT_BUFLEN+100);
BUF_ALLOC(&st->lbuf,"polypath lbuf");