udp: dict argument
address (string): IP address to listen and send on
port (integer): UDP port to listen and send on
+ resolver (resolver closure)
buffer (buffer closure): buffer for incoming packets
authbind (string): optional, path to authbind-helper program
+ udp looks up the following keys in its calling closure (usually, this
+ is a site closure) when a peer needs to be found:
+
+ address (string): optional, DNS name used to find our peer
+ port (integer): mandatory if 'address' is specified: the port used
+ to contact our peer
+
+
** log
Defines:
first one will be used for any key setups initiated by us using the
configured address. Others are only used if our peer talks to
them.
- resolver (resolver closure)
random (randomsrc closure)
local-key (rsaprivkey closure)
- address (string): optional, DNS name used to find our peer
- port (integer): mandatory if 'address' is specified: the port used
- to contact our peer
key (rsapubkey closure): our peer's public key
transform (transform closure): how to mangle packets sent between sites
dh (dh closure)
check that there are no links both ends of which are allegedly
mobile (which is not supported, so those links are ignored) and
to change some of the tuning parameter defaults. [false]
+ Plus further keys depending on the first comm.
Links involving mobile peers have some different tuning parameter
default values, which are generally more aggressive about retrying key
comm_notify_fn *fn);
typedef bool_t comm_sendmsg_fn(void *commst, struct buffer_if *buf,
const struct comm_addr *dest);
-typedef bool_t comm_addr_construct_fn(void *commst, struct comm_addr *ca,
- const struct sockaddr_in *sin);
- /* Fills in ca->comm an ca->priv. *sin must have no nonzero padding,
- so must have been FILLZERO'd before its useful fields were filled in.
- The resulting ca->comm has been constructed likewise, as required
- above. On failure, logs error, returns false on failure.*/
+typedef void *comm_peer_addr_config_fn(void *commst, dict_t*, struct cloc,
+ cstring_t desc);
+ /* Checks the config for the peer as specified in dict,
+ * and either returns NULL to mean the relevant parameters
+ * weren't specified, or a non-NULL void* which can be
+ * passed to comm_peer_addr_fn */
+typedef void comm_peer_addr_answer_fn(void *st, const struct comm_addr *ca);
+typedef bool_t comm_peer_addr_request_fn(void *commst, void *from_peer_config,
+ comm_peer_addr_answer_fn *cb, void *cst);
+ /* Calls comm_peer_addr_answer_fn, either immediately or later,
+ * with a suitable comm_addr. The caller's cb should
+ * memcpy ca. On failure, logs error and calls cb with ca=NULL */
typedef const char *comm_addr_to_string_fn(void *commst,
const struct comm_addr *ca);
/* Returned string is in a static buffer. */
comm_request_notify_fn *request_notify;
comm_release_notify_fn *release_notify;
comm_sendmsg_fn *sendmsg;
- comm_addr_construct_fn *addr_construct;
+ comm_peer_addr_config_fn *peer_addr_config;
+ comm_peer_addr_request_fn *peer_addr_request;
comm_addr_to_string_fn *addr_to_string;
};
bool_t peer_mobile; /* Mobile client support */
int32_t transport_peers_max;
string_t tunname; /* localname<->remotename by default, used in logs */
- string_t address; /* DNS name for bootstrapping, optional */
- int remoteport; /* Port for bootstrapping, optional */
+ void *remote_addr_config; /* created and used by comm */
struct netlink_if *netlink;
struct comm_if **comms;
int ncomms;
- struct resolver_if *resolver;
struct log_if *log;
struct random_if *random;
struct rsaprivkey_if *privkey;
}
}
-static void site_resolve_callback(void *sst, struct in_addr *address)
+static void site_resolve_callback(void *sst, const struct comm_addr *address)
{
struct site *st=sst;
- struct comm_addr ca_buf, *ca_use=0;
if (st->state!=SITE_RESOLVE) {
slog(st,LOG_UNEXPECTED,"site_resolve_callback called unexpectedly");
return;
}
- if (address) {
- struct sockaddr_in sin;
- FILLZERO(sin);
- sin.sin_family=AF_INET;
- sin.sin_port=htons(st->remoteport);
- sin.sin_addr=*address;
- if (st->comms[0]->addr_construct(st->comms[0]->st, &ca_buf, &sin)) {
- ca_use=&ca_buf;
- }
- } else {
- slog(st,LOG_ERROR,"resolution of %s failed",st->address);
+ if (!address) {
+ slog(st,LOG_ERROR,"resolution of peer address failed");
}
- if (transport_compute_setupinit_peers(st,ca_use)) {
+ if (transport_compute_setupinit_peers(st,address)) {
enter_new_state(st,SITE_SENTMSG1);
} else {
/* Can't figure out who to try to to talk to */
{
if (st->state!=SITE_RUN) return False;
slog(st,LOG_SETUP_INIT,"initiating key exchange (%s)",reason);
- if (st->address) {
+ if (st->remote_addr_config) {
slog(st,LOG_SETUP_INIT,"resolving peer address");
return enter_state_resolve(st);
} else if (transport_compute_setupinit_peers(st,0)) {
quality=LINK_QUALITY_UP;
else if (st->state==SITE_WAIT || st->state==SITE_STOP)
quality=LINK_QUALITY_DOWN;
- else if (st->address)
+ else if (st->remote_addr_config)
quality=LINK_QUALITY_DOWN_CURRENT_ADDRESS;
else if (transport_peers_valid(&st->peers))
quality=LINK_QUALITY_DOWN_STALE_ADDRESS;
state_assert(st,st->state==SITE_RUN);
slog(st,LOG_STATE,"entering state RESOLVE");
st->state=SITE_RESOLVE;
- st->resolver->request(st->resolver->st,st->address,
- site_resolve_callback,st);
+ st->comms[0]->peer_addr_request(st->comms[0]->st,st->remote_addr_config,
+ site_resolve_callback,st);
return True;
}
st->comms[i]=cl->interface;
}
- st->resolver=find_cl_if(dict,"resolver",CL_RESOLVER,True,"site",loc);
st->log=find_cl_if(dict,"log",CL_LOG,True,"site",loc);
st->random=find_cl_if(dict,"random",CL_RANDOMSRC,True,"site",loc);
+ st->remote_addr_config=st->comms[0]->peer_addr_config(
+ st->comms[0]->st,dict,loc,"site");
st->privkey=find_cl_if(dict,"local-key",CL_RSAPRIVKEY,True,"site",loc);
- st->address=dict_read_string(dict, "address", False, "site", loc);
- if (st->address)
- st->remoteport=dict_read_number(dict,"port",True,"site",loc,0);
- else st->remoteport=0;
st->pubkey=find_cl_if(dict,"key",CL_RSAPUBKEY,True,"site",loc);
st->transform=
};
system {
};
-resolver adns {
-};
log-events "all";
random randomfile("/dev/urandom",no);
transform serpent256-cbc {
+include test-example/top.conf
netlink tun {
name "netlink-tun"; # Printed in log messages from this netlink
local-address "172.18.232.9";
+include test-example/top.conf
netlink tun {
name "netlink-tun"; # Printed in log messages from this netlink
local-address "172.18.232.1";
--- /dev/null
+resolver adns {
+};
struct notify_list *next;
};
+struct peer_config {
+ string_t address; /* DNS name for bootstrapping, optional */
+ int remoteport; /* Port for bootstrapping, optional */
+};
+
struct udp {
closure_t cl;
struct comm_if ops;
string_t authbind;
struct buffer_if *rbuf;
struct notify_list *notify;
+ struct resolver_if *resolver;
bool_t use_proxy;
struct sockaddr_in proxy;
};
return sbuf;
}
-static bool_t addr_construct(void *commst, struct comm_addr *ca,
- const struct sockaddr_in *sin) {
+struct peer_addr_cst {
+ struct udp *udp;
+ struct peer_config *cfg;
+ comm_peer_addr_answer_fn *cb;
+ void *cst;
+};
+
+static void *peer_addr_config(void *commst, dict_t *dict, struct cloc loc,
+ cstring_t desc)
+{
+ struct peer_config *cfg;
+ cfg=safe_malloc(sizeof(*cfg),"peer addr config");
+ cfg->address=dict_read_string(dict, "address",False,desc,loc);
+ if (cfg->address)
+ cfg->remoteport=dict_read_number(dict,"port",True,desc,loc,0);
+ else cfg->remoteport=0;
+ if (cfg->address)
+ return cfg;
+ free(cfg);
+ return NULL;
+}
+
+static void peer_resolve_callback(void *sst, struct in_addr *address)
+{
+ struct peer_addr_cst *pacst=sst;
+ struct udp *st=pacst->udp;
+ struct peer_config *cfg=pacst->cfg;
+ struct comm_addr ca;
+ if (address) {
+ FILLZERO(ca);
+ ca.comm=&st->ops;
+ ca.priv.sin.sin_family=AF_INET;
+ ca.priv.sin.sin_port=htons(cfg->remoteport);
+ ca.priv.sin.sin_addr=*address;
+ pacst->cb(pacst->cst,&ca);
+ } else {
+ pacst->cb(pacst->cst,0);
+ }
+ free(pacst);
+}
+
+static bool_t peer_addr_request(void *commst, void *from_peer_config,
+ comm_peer_addr_answer_fn *cb, void *cst)
+{
struct udp *st=commst;
- FILLZERO(*ca);
- ca->comm=&st->ops;
- ca->priv.sin=*sin;
- return True;
+ struct peer_config *cfg=from_peer_config;
+ struct peer_addr_cst *pacst;
+ pacst=safe_malloc(sizeof(*pacst),"udp peer addr request cst");
+ pacst->udp=st;
+ pacst->cfg=cfg;
+ pacst->cb=cb;
+ pacst->cst=cst;
+ bool_t ok=st->resolver->request(st->resolver->st,cfg->address,
+ peer_resolve_callback,pacst);
+ if (!ok)
+ free(pacst);
+ return ok;
}
static int udp_beforepoll(void *state, struct pollfd *fds, int *nfds_io,
st->ops.request_notify=request_notify;
st->ops.release_notify=release_notify;
st->ops.sendmsg=udp_sendmsg;
- st->ops.addr_construct=addr_construct;
+ st->ops.peer_addr_config=peer_addr_config;
+ st->ops.peer_addr_request=peer_addr_request;
st->ops.addr_to_string=addr_to_string;
st->port=0;
st->use_proxy=False;
st->proxy.sin_port=htons(i->data.number);
st->ops.min_start_pad=8;
}
+ st->resolver=find_cl_if(d,"resolver",CL_RESOLVER,True,"comm",loc);
add_hook(PHASE_GETRESOURCES,udp_phase_hook,st);