chiark / gitweb /
resolver: Log reason for DNS resolution failure
[secnet.git] / site.c
diff --git a/site.c b/site.c
index 2a84fd20cd8e042509b38bafaa403def4f37c30f..15dace88d3c74f0e22a35b891d91a061c311877e 100644 (file)
--- a/site.c
+++ b/site.c
@@ -40,7 +40,6 @@
 #define DEFAULT_MOBILE_WAIT_TIME                (10*1000) /* [ms] */
 
 #define DEFAULT_MOBILE_PEER_EXPIRY            (2*60)      /* [s] */
-#define DEFAULT_MOBILE_PEERS_MAX 3 /* send at most this many copies (default) */
 
 /* Each site can be in one of several possible states. */
 
@@ -144,9 +143,6 @@ static struct flagstr log_event_table[]={
 
 /* Details of "mobile peer" semantics:
 
- | Note: this comment is wishful thinking right now.  It will be
- | implemented in subsequent commits.
-
    - We use the same data structure for the different configurations,
      but manage it with different algorithms.
    
@@ -220,8 +216,6 @@ static struct flagstr log_event_table[]={
 
    */
 
-#define MAX_MOBILE_PEERS_MAX 5 /* send at most this many copies, compiled max */
-
 typedef struct {
     struct timeval last;
     struct comm_addr addr;
@@ -231,7 +225,7 @@ typedef struct {
 /* configuration information */
 /* runtime information */
     int npeers;
-    transport_peer peers[MAX_MOBILE_PEERS_MAX];
+    transport_peer peers[MAX_PEER_ADDRS];
 } transport_peers;
 
 /* Basic operations on transport peer address sets */
@@ -1196,29 +1190,24 @@ 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 *addrs,
+                                 int naddrs, int was_naddrs,
+                                 const char *failwhy)
 {
     struct site *st=sst;
-    struct comm_addr ca_buf;
-    const struct comm_addr *addrs;
-    int naddrs;
 
     st->resolving=False;
 
-    if (address) {
-       FILLZERO(ca_buf);
-       ca_buf.comm=st->comms[0];
-       ca_buf.sin.sin_family=AF_INET;
-       ca_buf.sin.sin_port=htons(st->remoteport);
-       ca_buf.sin.sin_addr=*address;
-       addrs=&ca_buf;
-       naddrs=1;
-       slog(st,LOG_STATE,"resolution of %s completed: %s",
-            st->address, comm_addr_to_string(&addrs[0]));;
+    if (naddrs) {
+       slog(st,LOG_STATE,"resolution of %s completed, %d addrs, eg: %s",
+            st->address, was_naddrs, comm_addr_to_string(&addrs[0]));;
+       if (naddrs != was_naddrs) {
+           slog(st,LOG_SETUP_INIT,"resolution of supplied addresses/names"
+                " yielded too many results (%d > %d), some ignored",
+                was_naddrs, naddrs);
+       }
     } else {
-       slog(st,LOG_ERROR,"resolution of %s failed",st->address);
-       addrs=0;
-       naddrs=0;
+       slog(st,LOG_ERROR,"resolution of %s failed: %s",st->address,failwhy);
     }
 
     switch (st->state) {
@@ -1405,6 +1394,7 @@ static bool_t ensure_resolving(struct site *st)
      * case we have to clear ->resolving again. */
     st->resolving=True;
     bool_t ok = st->resolver->request(st->resolver->st,st->address,
+                                     st->remoteport,st->comms[0],
                                      site_resolve_callback,st);
     if (!ok)
        st->resolving=False;
@@ -1972,12 +1962,14 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     st->mobile_peer_expiry= dict_read_number(
        dict,"mobile-peer-expiry",False,"site",loc,DEFAULT_MOBILE_PEER_EXPIRY);
 
-    st->transport_peers_max= !st->peer_mobile ? 1 : dict_read_number(
-       dict,"mobile-peers-max",False,"site",loc,DEFAULT_MOBILE_PEERS_MAX);
+    const char *peerskey= st->peer_mobile
+       ? "mobile-peers-max" : "static-peers-max";
+    st->transport_peers_max= dict_read_number(
+       dict,peerskey,False,"site",loc, st->address ? 4 : 3);
     if (st->transport_peers_max<1 ||
-       st->transport_peers_max>MAX_MOBILE_PEERS_MAX) {
-       cfgfatal(loc,"site","mobile-peers-max must be in range 1.."
-                STRING(MAX_MOBILE_PEERS_MAX) "\n");
+       st->transport_peers_max>MAX_PEER_ADDRS) {
+       cfgfatal(loc,"site", "%s must be in range 1.."
+                STRING(MAX_PEER_ADDRS) "\n", peerskey);
     }
 
     if (st->key_lifetime < DEFAULT(KEY_RENEGOTIATE_GAP)*2)
@@ -2097,11 +2089,6 @@ static void transport_peers_debug(struct site *st, transport_peers *dst,
     }
 }
 
-static bool_t transport_addrs_equal(const struct comm_addr *a,
-                                   const struct comm_addr *b) {
-    return !memcmp(a,b,sizeof(*a));
-}
-
 static void transport_peers_expire(struct site *st, transport_peers *peers) {
     /* peers must be sorted first */
     int previous_peers=peers->npeers;
@@ -2125,7 +2112,7 @@ static bool_t transport_peer_record_one(struct site *st, transport_peers *peers,
        return 0;
 
     for (search=0; search<peers->npeers; search++)
-       if (transport_addrs_equal(&peers->peers[search].addr, ca))
+       if (comm_addr_equal(&peers->peers[search].addr, ca))
            return 1;
 
     peers->peers[peers->npeers].addr = *ca;
@@ -2144,7 +2131,7 @@ static void transport_record_peers(struct site *st, transport_peers *peers,
      * Caller must first call transport_peers_expire. */
 
     if (naddrs==1 && peers->npeers>=1 &&
-       transport_addrs_equal(&addrs[0], &peers->peers[0].addr)) {
+       comm_addr_equal(&addrs[0], &peers->peers[0].addr)) {
        /* optimisation, also avoids debug for trivial updates */
        peers->peers[0].last = *tv_now;
        return;
@@ -2192,11 +2179,11 @@ static bool_t transport_compute_setupinit_peers(struct site *st,
         incoming_packet_addr ? " incoming packet address;" : "",
         st->peers.npeers);
 
-    /* Non-mobile peers have st->peers.npeers==0 or ==1, since they
-     * have transport_peers_max==1.  The effect is that this code
-     * always uses the configured address if supplied, or otherwise
-     * the address of the incoming PROD, or the existing data peer if
-     * one exists; this is as desired. */
+    /* Non-mobile peers try addresses until one is plausible.  The
+     * effect is that this code always tries first the configured
+     * address if supplied, or otherwise the address of the incoming
+     * PROD, or finally the existing data peer if one exists; this is
+     * as desired. */
 
     transport_peers_copy(st,&st->setup_peers,&st->peers);
     transport_peers_expire(st,&st->setup_peers);
@@ -2273,7 +2260,7 @@ void transport_xmit(struct site *st, transport_peers *peers,
     int slot;
     transport_peers_expire(st, peers);
     unsigned failed=0; /* bitmask */
-    assert(MAX_MOBILE_PEERS_MAX < sizeof(unsigned)*CHAR_BIT);
+    assert(MAX_PEER_ADDRS < sizeof(unsigned)*CHAR_BIT);
 
     int nfailed=0;
     for (slot=0; slot<peers->npeers; slot++) {