/* 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"
#define SITE_SENTMSG5 7
#define SITE_WAIT 8
+#if 0
static string_t state_name(uint32_t state)
{
switch (state) {
default: return "*bad state*";
}
}
+#endif /* 0 */
#define LABEL_MSG0 0x00020200
#define LABEL_MSG1 0x01010101
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 */
}
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. */
}
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;
}
/* 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;
}
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);
/* 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);
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);