*
* secnet is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version d of the License, or
+ * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* secnet is distributed in the hope that it will be useful, but
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[] = {
const char *const *pati;
for (pati=pats; *pati; pati++) {
const char *pat=*pati;
- if (*pat=='!' || *pat=='+') { *want_io=*pat; pat++; }
+ if (*pat=='!' || *pat=='+' || *pat=='@') { *want_io=*pat; pat++; }
else if (*pat=='*' || isalnum((unsigned char)*pat)) { *want_io='+'; }
else cfgfatal(loc,"polypath","invalid interface name pattern `%s'",pat);
int match=fnmatch(pat,ifname,0);
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; break;
+ case '@': interfs=&st->interfs_dedicated; max_interfs=INT_MAX; break;
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");