chiark / gitweb /
Import release 0.1.1
[secnet.git] / site.c
diff --git a/site.c b/site.c
index 4ca53cd75eaed2aeb3548a7f3716f99ebe3d628c..9bfbf9d50f99fff73ff2e0116bb79c568386a4d3 100644 (file)
--- a/site.c
+++ b/site.c
@@ -1,9 +1,11 @@
 /* site.c - manage communication with a remote network site */
 
+#include "secnet.h"
 #include <stdio.h>
-#include <sys/mman.h>
+/* MBM asserts the next one is needed for compilation under BSD. */
+#include <sys/socket.h>
 
-#include "secnet.h"
+#include <sys/mman.h>
 #include "util.h"
 #include "unaligned.h"
 
@@ -61,6 +63,7 @@
 #define SITE_SENTMSG5 7
 #define SITE_WAIT     8
 
+#if 0
 static string_t state_name(uint32_t state)
 {
     switch (state) {
@@ -76,6 +79,7 @@ static string_t state_name(uint32_t state)
     default: return "*bad state*";
     }
 }
+#endif /* 0 */
 
 #define LABEL_MSG0 0x00020200
 #define LABEL_MSG1 0x01010101
@@ -700,7 +704,7 @@ static void enter_state_run(struct site *st)
     slog(st,LOG_STATE,"entering state RUN");
     st->state=SITE_RUN;
     st->timeout=0;
-    st->netlink->set_delivery(st->netlink->st,st->netlink_cid,True);
+    st->netlink->set_quality(st->netlink->st,st->netlink_cid,LINK_QUALITY_UP);
     /* XXX get rid of key setup data */
 }
 
@@ -817,7 +821,8 @@ static void enter_state_wait(struct site *st)
     st->timeout=st->now+st->wait_timeout;
     st->state=SITE_WAIT;
     st->peer_valid=False;
-    st->netlink->set_delivery(st->netlink->st,st->netlink_cid,False);
+    st->netlink->set_quality(st->netlink->st,st->netlink_cid,
+                            LINK_QUALITY_DOWN);
     BUF_FREE(&st->buffer); /* will have had an outgoing packet in it */
     /* XXX Erase keys etc. */
 }
@@ -888,13 +893,15 @@ static void site_outgoing(void *sst, void *cid, struct buffer_if *buf)
        a valid key and a valid address to send it to. */
     if (st->current_valid && st->peer_valid) {
        /* Transform it and send it */
-       buf_prepend_uint32(buf,LABEL_MSG9);
-       st->current_transform->forwards(st->current_transform->st,
-                                       buf, &transform_err);
-       buf_prepend_uint32(buf,LABEL_MSG0);
-       buf_prepend_uint32(buf,(uint32_t)st);
-       buf_prepend_uint32(buf,st->remote_session_id);
-       st->comm->sendmsg(st->comm->st,buf,&st->peer);
+       if (buf->size>0) {
+           buf_prepend_uint32(buf,LABEL_MSG9);
+           st->current_transform->forwards(st->current_transform->st,
+                                           buf, &transform_err);
+           buf_prepend_uint32(buf,LABEL_MSG0);
+           buf_prepend_uint32(buf,(uint32_t)st);
+           buf_prepend_uint32(buf,st->remote_session_id);
+           st->comm->sendmsg(st->comm->st,buf,&st->peer);
+       }
        BUF_FREE(buf);
        return;
     }
@@ -908,7 +915,7 @@ static void site_outgoing(void *sst, void *cid, struct buffer_if *buf)
 
     /* Otherwise we're in the middle of key setup or a wait - just
        throw the outgoing packet away */
-    slog(st,LOG_DROP,"discarding outgoing packet");
+    slog(st,LOG_DROP,"discarding outgoing packet of size %d",buf->size);
     BUF_FREE(buf);
     return;
 }
@@ -1086,17 +1093,26 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
        cfgfatal(loc,"site","parameter must be a dictionary\n");
     
     dict=item->data.dict;
+    st->localname=dict_read_string(dict, "local-name", True, "site", loc);
+    st->remotename=dict_read_string(dict, "name", True, "site", loc);
+    /* Sanity check (which also allows the 'sites' file to include
+       site() closures for all sites including our own): refuse to
+       talk to ourselves */
+    if (strcmp(st->localname,st->remotename)==0) {
+       Message(M_INFO,"site %s: local-name==name -> ignoring this site\n",
+               st->localname);
+       free(st);
+       return NULL;
+    }
     st->netlink=find_cl_if(dict,"netlink",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);
     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->localname=dict_read_string(dict, "local-name", True, "site", loc);
     st->privkey=find_cl_if(dict,"local-key",CL_RSAPRIVKEY,True,"site",loc);
     st->remoteport=dict_read_number(dict,"port",True,"site",loc,0);
 
-    st->remotename=dict_read_string(dict, "name", True, "site", loc);
     st->address=dict_read_string(dict, "address", False, "site", loc);
     dict_read_subnet_list(dict, "networks", True, "site", loc,
                          &st->remotenets);
@@ -1128,11 +1144,10 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
     /* XXX fix this bit for unaligned access */
     st->setupsiglen=strlen(st->remotename)+strlen(st->localname)+8;
     st->setupsig=safe_malloc(st->setupsiglen,"site_apply");
-    *(uint32_t *)&(st->setupsig[0])=LABEL_MSG1;
-    *(uint16_t *)&(st->setupsig[4])=htons(strlen(st->remotename));
+    put_uint32(st->setupsig+0,LABEL_MSG1);
+    put_uint16(st->setupsig+4,strlen(st->remotename));
     memcpy(&st->setupsig[6],st->remotename,strlen(st->remotename));
-    *(uint16_t *)&(st->setupsig[6+strlen(st->remotename)])=
-       htons(strlen(st->localname));
+    put_uint16(st->setupsig+(6+strlen(st->remotename)),strlen(st->localname));
     memcpy(&st->setupsig[8+strlen(st->remotename)],st->localname,
           strlen(st->localname));
     st->setup_priority=(strcmp(st->localname,st->remotename)>0);
@@ -1157,6 +1172,11 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
                                         st->transform->max_start_pad+(4*4),
                                         st->transform->max_end_pad,
                                         st->tunname);
+    if (!st->netlink_cid) {
+       fatal("%s: netlink device did not let us register our remote "
+             "networks. Check that they are not local or excluded.\n",
+             st->tunname);
+    }
 
     st->comm->request_notify(st->comm->st, st, site_incoming);