- uint32_t setup_retries; /* How many times to send setup packets */
- uint32_t setup_timeout; /* Initial timeout for setup packets */
- uint32_t wait_timeout; /* How long to wait if setup unsuccessful */
- uint32_t key_lifetime; /* How long a key lasts once set up */
- uint32_t key_renegotiate_time; /* If we see traffic (or a keepalive)
+ uint32_t index; /* Index of this site */
+ int32_t setup_retries; /* How many times to send setup packets */
+ int32_t setup_timeout; /* Initial timeout for setup packets */
+ int32_t wait_timeout; /* How long to wait if setup unsuccessful */
+ int32_t key_lifetime; /* How long a key lasts once set up */
+ int32_t key_renegotiate_time; /* If we see traffic (or a keepalive)
after this time, initiate a new
key exchange */
bool_t keepalive; /* Send keepalives to detect peer failure (not yet
implemented) */
uint8_t *setupsig; /* Expected signature of incoming MSG1 packets */
after this time, initiate a new
key exchange */
bool_t keepalive; /* Send keepalives to detect peer failure (not yet
implemented) */
uint8_t *setupsig; /* Expected signature of incoming MSG1 packets */
uint8_t localN[NONCELEN]; /* Nonces for key exchange */
uint8_t remoteN[NONCELEN];
struct buffer_if buffer; /* Current outgoing key exchange packet */
uint8_t localN[NONCELEN]; /* Nonces for key exchange */
uint8_t remoteN[NONCELEN];
struct buffer_if buffer; /* Current outgoing key exchange packet */
static void slog(struct site *st, uint32_t event, cstring_t msg, ...)
{
va_list ap;
static void slog(struct site *st, uint32_t event, cstring_t msg, ...)
{
va_list ap;
- vsnprintf(buf,240,msg,ap);
+ vsnprintf(buf,sizeof(buf),msg,ap);
st->log->log(st->log->st,class,"%s: %s",st->tunname,buf);
}
va_end(ap);
st->log->log(st->log->st,class,"%s: %s",st->tunname,buf);
}
va_end(ap);
buffer_init(&st->buffer,0);
buf_append_uint32(&st->buffer,
(type==LABEL_MSG1?0:st->setup_session_id));
buffer_init(&st->buffer,0);
buf_append_uint32(&st->buffer,
(type==LABEL_MSG1?0:st->setup_session_id));
buf_append_uint32(&st->buffer,type);
buf_append_string(&st->buffer,st->localname);
buf_append_string(&st->buffer,st->remotename);
buf_append_uint32(&st->buffer,type);
buf_append_string(&st->buffer,st->localname);
buf_append_string(&st->buffer,st->remotename);
if (type==LABEL_MSG1) return True;
memcpy(buf_append(&st->buffer,NONCELEN),st->remoteN,NONCELEN);
if (type==LABEL_MSG2) return True;
if (type==LABEL_MSG1) return True;
memcpy(buf_append(&st->buffer,NONCELEN),st->remoteN,NONCELEN);
if (type==LABEL_MSG2) return True;
dhpub=st->dh->makepublic(st->dh->st,st->dhsecret,st->dh->len);
buf_append_string(&st->buffer,dhpub);
free(dhpub);
dhpub=st->dh->makepublic(st->dh->st,st->dhsecret,st->dh->len);
buf_append_string(&st->buffer,dhpub);
free(dhpub);
hst=st->hash->init();
st->hash->update(hst,st->buffer.start,st->buffer.size);
st->hash->final(hst,hash);
sig=st->privkey->sign(st->privkey->st,hash,st->hash->len);
buf_append_string(&st->buffer,sig);
free(sig);
hst=st->hash->init();
st->hash->update(hst,st->buffer.start,st->buffer.size);
st->hash->final(hst,hash);
sig=st->privkey->sign(st->privkey->st,hash,st->hash->len);
buf_append_string(&st->buffer,sig);
free(sig);
hst=st->hash->init();
st->hash->update(hst,m.hashstart,m.hashlen);
st->hash->final(hst,hash);
hst=st->hash->init();
st->hash->update(hst,m.hashstart,m.hashlen);
st->hash->final(hst,hash);
m.sig[m.siglen]=0;
if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
slog(st,LOG_SEC,"msg3 signature failed check!");
m.sig[m.siglen]=0;
if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
slog(st,LOG_SEC,"msg3 signature failed check!");
hst=st->hash->init();
st->hash->update(hst,m.hashstart,m.hashlen);
st->hash->final(hst,hash);
hst=st->hash->init();
st->hash->update(hst,m.hashstart,m.hashlen);
st->hash->final(hst,hash);
m.sig[m.siglen]=0;
if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
slog(st,LOG_SEC,"msg4 signature failed check!");
m.sig[m.siglen]=0;
if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
slog(st,LOG_SEC,"msg4 signature failed check!");
st->new_transform->forwards(st->new_transform->st,&st->buffer,
&transform_err);
buf_prepend_uint32(&st->buffer,LABEL_MSG5);
st->new_transform->forwards(st->new_transform->st,&st->buffer,
&transform_err);
buf_prepend_uint32(&st->buffer,LABEL_MSG5);
buf_prepend_uint32(&st->buffer,st->setup_session_id);
st->retries=st->setup_retries;
buf_prepend_uint32(&st->buffer,st->setup_session_id);
st->retries=st->setup_retries;
st->new_transform->forwards(st->new_transform->st,&st->buffer,
&transform_err);
buf_prepend_uint32(&st->buffer,LABEL_MSG6);
st->new_transform->forwards(st->new_transform->st,&st->buffer,
&transform_err);
buf_prepend_uint32(&st->buffer,LABEL_MSG6);
buf_prepend_uint32(&st->buffer,st->setup_session_id);
st->retries=1; /* Peer will retransmit MSG5 if this packet gets lost */
buf_prepend_uint32(&st->buffer,st->setup_session_id);
st->retries=1; /* Peer will retransmit MSG5 if this packet gets lost */
- log(st->log,M_DEBUG,"%s: %s: %08x<-%08x: %08x:",
- st->tunname,incoming?"incoming":"outgoing",
- dest,source,msgtype);
+ slilog(st->log,M_DEBUG,"%s: %s: %08x<-%08x: %08x:",
+ st->tunname,incoming?"incoming":"outgoing",
+ dest,source,msgtype);
static bool_t enter_new_state(struct site *st, uint32_t next)
{
bool_t (*gen)(struct site *st);
static bool_t enter_new_state(struct site *st, uint32_t next)
{
bool_t (*gen)(struct site *st);
slog(st,LOG_STATE,"entering state %s",state_name(next));
switch(next) {
case SITE_SENTMSG1:
slog(st,LOG_STATE,"entering state %s",state_name(next));
switch(next) {
case SITE_SENTMSG1:
- if (gen(st) && send_msg(st)) {
+ if (hacky_par_start_failnow()) return False;
+
+ r= gen(st) && send_msg(st);
+
+ hacky_par_end(&r,
+ st->setup_retries, st->setup_timeout,
+ send_msg, st);
+
+ if (r) {
st->current_transform->forwards(st->current_transform->st,
&st->buffer, &transform_err);
buf_prepend_uint32(&st->buffer,LABEL_MSG0);
st->current_transform->forwards(st->current_transform->st,
&st->buffer, &transform_err);
buf_prepend_uint32(&st->buffer,LABEL_MSG0);
buf_prepend_uint32(&st->buffer,st->remote_session_id);
st->comm->sendmsg(st->comm->st,&st->buffer,&st->peer);
BUF_FREE(&st->buffer);
buf_prepend_uint32(&st->buffer,st->remote_session_id);
st->comm->sendmsg(st->comm->st,&st->buffer,&st->peer);
BUF_FREE(&st->buffer);
}
static int site_beforepoll(void *sst, struct pollfd *fds, int *nfds_io,
}
static int site_beforepoll(void *sst, struct pollfd *fds, int *nfds_io,
/* Work out when our next timeout is. The earlier of 'timeout' or
'current_key_timeout'. A stored value of '0' indicates no timeout
active. */
/* Work out when our next timeout is. The earlier of 'timeout' or
'current_key_timeout'. A stored value of '0' indicates no timeout
active. */
- site_settimeout(st->timeout, now, timeout_io);
- site_settimeout(st->current_key_timeout, now, timeout_io);
+ site_settimeout(st->timeout, timeout_io);
+ site_settimeout(st->current_key_timeout, timeout_io);
-static void site_afterpoll(void *sst, struct pollfd *fds, int nfds,
- const struct timeval *tv_now, uint64_t *now)
+static void site_afterpoll(void *sst, struct pollfd *fds, int nfds)
- if (st->state>=SITE_SENTMSG1 && st->state<=SITE_SENTMSG5)
- send_msg(st);
- else if (st->state==SITE_WAIT) {
+ if (st->state>=SITE_SENTMSG1 && st->state<=SITE_SENTMSG5) {
+ if (!hacky_par_start_failnow())
+ send_msg(st);
+ } else if (st->state==SITE_WAIT) {
enter_state_run(st);
} else {
slog(st,LOG_ERROR,"site_afterpoll: unexpected timeout, state=%d",
enter_state_run(st);
} else {
slog(st,LOG_ERROR,"site_afterpoll: unexpected timeout, state=%d",
st->current_transform->forwards(st->current_transform->st,
buf, &transform_err);
buf_prepend_uint32(buf,LABEL_MSG0);
st->current_transform->forwards(st->current_transform->st,
buf, &transform_err);
buf_prepend_uint32(buf,LABEL_MSG0);
buf_prepend_uint32(buf,st->remote_session_id);
st->comm->sendmsg(st->comm->st,buf,&st->peer);
}
buf_prepend_uint32(buf,st->remote_session_id);
st->comm->sendmsg(st->comm->st,buf,&st->peer);
}
/* Explicitly addressed to us */
uint32_t msgtype=ntohl(get_uint32(buf->start+8));
if (msgtype!=LABEL_MSG0) dump_packet(st,buf,source,True);
/* Explicitly addressed to us */
uint32_t msgtype=ntohl(get_uint32(buf->start+8));
if (msgtype!=LABEL_MSG0) dump_packet(st,buf,source,True);
static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
list_t *args)
{
static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context,
list_t *args)
{
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);
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);
st->key_lifetime=dict_read_number(
dict,"key-lifetime",False,"site",loc,DEFAULT_KEY_LIFETIME);
st->key_lifetime=dict_read_number(
dict,"key-lifetime",False,"site",loc,DEFAULT_KEY_LIFETIME);
st->setup_retries=dict_read_number(
dict,"setup-retries",False,"site",loc,DEFAULT_SETUP_RETRIES);
st->setup_timeout=dict_read_number(
dict,"setup-timeout",False,"site",loc,DEFAULT_SETUP_TIMEOUT);
st->wait_timeout=dict_read_number(
dict,"wait-time",False,"site",loc,DEFAULT_WAIT_TIME);
st->setup_retries=dict_read_number(
dict,"setup-retries",False,"site",loc,DEFAULT_SETUP_RETRIES);
st->setup_timeout=dict_read_number(
dict,"setup-timeout",False,"site",loc,DEFAULT_SETUP_TIMEOUT);
st->wait_timeout=dict_read_number(
dict,"wait-time",False,"site",loc,DEFAULT_WAIT_TIME);
- dict,"renegotiate-time",False,"site",loc,st->key_lifetime);
+ dict,"renegotiate-time",False,"site",loc,st->key_renegotiate_time);
if (st->key_renegotiate_time > st->key_lifetime) {
cfgfatal(loc,"site",
"renegotiate-time must be less than key-lifetime\n");
if (st->key_renegotiate_time > st->key_lifetime) {
cfgfatal(loc,"site",
"renegotiate-time must be less than key-lifetime\n");
sprintf(st->tunname,"%s<->%s",st->localname,st->remotename);
/* The information we expect to see in incoming messages of type 1 */
sprintf(st->tunname,"%s<->%s",st->localname,st->remotename);
/* The information we expect to see in incoming messages of type 1 */
st->setupsiglen=strlen(st->remotename)+strlen(st->localname)+8;
st->setupsig=safe_malloc(st->setupsiglen,"site_apply");
put_uint32(st->setupsig+0,LABEL_MSG1);
st->setupsiglen=strlen(st->remotename)+strlen(st->localname)+8;
st->setupsig=safe_malloc(st->setupsiglen,"site_apply");
put_uint32(st->setupsig+0,LABEL_MSG1);
void site_module(dict_t *dict)
{
add_closure(dict,"site",site_apply);
void site_module(dict_t *dict)
{
add_closure(dict,"site",site_apply);