chiark / gitweb /
comm,site: Make peer address configuration the responsibility of comm (udp)
[secnet.git] / site.c
diff --git a/site.c b/site.c
index ed9e803b308211a01a10930fcfadfcc33dcc3be7..88924009618bc6189c1c47458125cf057a9137a6 100644 (file)
--- a/site.c
+++ b/site.c
@@ -223,11 +223,10 @@ struct site {
     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 *comm;
-    struct resolver_if *resolver;
+    struct comm_if **comms;
+    int ncomms;
     struct log_if *log;
     struct random_if *random;
     struct rsaprivkey_if *privkey;
@@ -792,27 +791,18 @@ static bool_t send_msg(struct site *st)
     }
 }
 
-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;
 
     if (st->state!=SITE_RESOLVE) {
        slog(st,LOG_UNEXPECTED,"site_resolve_callback called unexpectedly");
        return;
     }
-    if (address) {
-       FILLZERO(ca_buf);
-       ca_buf.comm=st->comm;
-       ca_buf.sin.sin_family=AF_INET;
-       ca_buf.sin.sin_port=htons(st->remoteport);
-       ca_buf.sin.sin_addr=*address;
-       ca_use=&ca_buf;
-    } else {
-       slog(st,LOG_ERROR,"resolution of %s failed",st->address);
-       ca_use=0;
+    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 */
@@ -825,7 +815,7 @@ static bool_t initiate_key_setup(struct site *st, cstring_t reason)
 {
     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)) {
@@ -889,7 +879,7 @@ static void set_link_quality(struct site *st)
        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;
@@ -920,8 +910,8 @@ static bool_t enter_state_resolve(struct site *st)
     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;
 }
 
@@ -1288,6 +1278,7 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     struct site *st;
     item_t *item;
     dict_t *dict;
+    int i;
 
     st=safe_malloc(sizeof(*st),"site_apply");
 
@@ -1335,16 +1326,26 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     assert(index_sequence < 0xffffffffUL);
     st->index = ++index_sequence;
     st->netlink=find_cl_if(dict,"link",CL_NETLINK,True,"site",loc);
-    st->comm=find_cl_if(dict,"comm",CL_COMM,True,"site",loc);
-    st->resolver=find_cl_if(dict,"resolver",CL_RESOLVER,True,"site",loc);
+
+    list_t *comms_cfg=dict_lookup(dict,"comm");
+    if (!comms_cfg) cfgfatal(loc,"site","closure list \"comm\" not found");
+    st->ncomms=list_length(comms_cfg);
+    st->comms=safe_malloc_ary(sizeof(*st->comms),st->ncomms,"comms");
+    assert(st->ncomms);
+    for (i=0; i<st->ncomms; i++) {
+       item_t *item=list_elem(comms_cfg,i);
+       if (item->type!=t_closure) cfgfatal(loc,"site","comm is not a closure");
+       closure_t *cl=item->data.closure;
+       if (cl->type!=CL_COMM) cfgfatal(loc,"site","comm closure wrong type");
+       st->comms[i]=cl->interface;
+    }
+
     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=
@@ -1419,13 +1420,25 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     st->dhsecret=safe_malloc(st->dh->len,"site:dhsecret");
     st->sharedsecret=safe_malloc(st->transform->keylen,"site:sharedsecret");
 
+    /* We need to compute some properties of our comms */
+#define COMPUTE_WORST(pad)                     \
+    int worst_##pad=0;                         \
+    for (i=0; i<st->ncomms; i++) {             \
+       int thispad=st->comms[i]->pad;          \
+       if (thispad > worst_##pad)              \
+           worst_##pad=thispad;                \
+    }
+    COMPUTE_WORST(min_start_pad)
+    COMPUTE_WORST(min_end_pad)
+
     /* We need to register the remote networks with the netlink device */
     st->netlink->reg(st->netlink->st, site_outgoing, st,
                     st->transform->max_start_pad+(4*4)+
-                    st->comm->min_start_pad,
-                    st->transform->max_end_pad+st->comm->min_end_pad);
+                    worst_min_start_pad,
+                    st->transform->max_end_pad+worst_min_end_pad);
     
-    st->comm->request_notify(st->comm->st, st, site_incoming);
+    for (i=0; i<st->ncomms; i++)
+       st->comms[i]->request_notify(st->comms[i]->st, st, site_incoming);
 
     st->current_transform=st->transform->create(st->transform->st);
     st->new_transform=st->transform->create(st->transform->st);