static int isakmp_ph2begin_r __P((struct ph1handle *, vchar_t *));
static int etypesw1 __P((int));
static int etypesw2 __P((int));
+static void isakmp_free_addrs __P((void));
+
/*
* isakmp packet handler
plog(LLV_ERROR, LOCATION, (struct sockaddr *)&remote,
"packet shorter than isakmp header size.\n");
/* dummy receive */
+ if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
+ 0, (struct sockaddr *)&remote, &remote_len)) < 0) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "failed to receive isakmp packet\n");
+ }
+ goto end;
+ }
+
+ /* reject if the size is toooo big */
+ if (ntohl(isakmp.len) > 0xffff) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "the length of the isakmp header is too big.\n");
if ((len = recvfrom(so_isakmp, (char *)&isakmp, sizeof(isakmp),
0, (struct sockaddr *)&remote, &remote_len)) < 0) {
plog(LLV_ERROR, LOCATION, NULL,
goto end;
}
+ remote_len = sizeof(remote);
+
/* read real message */
if ((buf = vmalloc(ntohl(isakmp.len))) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
if (errno == EINTR)
continue;
plog(LLV_ERROR, LOCATION, NULL,
- "failed to receive isakmp packet\n");
+ "failed to read isakmp packet from socket %d, len=%d\n", so_isakmp, buf->l);
+ error = -2; /* serious problem with socket */
goto end;
}
goto end;
}
+ remote_len = sizeof(remote);
+
/* read real message */
if ((buf = vmalloc(ntohl(isakmp->len) + 4)) == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
if (errno == EINTR)
continue;
plog(LLV_ERROR, LOCATION, NULL,
- "failed to receive isakmp packet\n");
+ "failed to read isakmp packet from socket %d, len=%d\n", so_isakmp, buf->l);
+ error = -2; /* serious problem with socket */
goto end;
}
if (cmpsaddrstrict(iph1->remote, remote) != 0) {
#ifdef IKE_NAT_T
if (iph1->side == RESPONDER &&
- (iph1->natt_flags & natt_remote_support) != 0 &&
+ (iph1->natt_flags & NATT_TYPE_MASK) != 0 &&
cmpsaddrwop(iph1->remote, remote) == 0)
{
/*
return -1;
}
- /* when using commit bit, status will be reached here. */
- if (iph2->status == PHASE2ST_ADDSA)
- return 0;
-
/* free resend buffer */
if (iph2->sendbuf == NULL) {
plog(LLV_ERROR, LOCATION, NULL,
/* turn off schedule */
if (iph2->scr)
SCHED_KILL(iph2->scr);
+
+ /* when using commit bit, status will be reached here. */
+ if (iph2->status == PHASE2ST_ADDSA)
+ return 0;
/* send */
plog(LLV_DEBUG, LOCATION, NULL, "===\n");
for (p = lcconf->myaddrs; p; p = p->next) {
if (!p->addr)
continue;
-
+
+ if (p->sock != -1) {
+ ifnum++;
+ continue; // socket already open
+ }
+
/* warn if wildcard address - should we forbid this? */
switch (p->addr->sa_family) {
case AF_INET:
{
struct sockaddr_in sin = *(struct sockaddr_in*)p->addr;
- sin.sin_port = ntohs(PORT_ISAKMP_NATT);
+ sin.sin_port = htons(PORT_ISAKMP_NATT);
p->nattsock = isakmp_setup_socket((struct sockaddr*)&sin);
if (p->nattsock >= 0)
- {
plog(LLV_DEBUG, LOCATION, NULL,
"%s used as nat-t isakmp port (fd=%d)\n",
saddr2str((struct sockaddr*)&sin), p->nattsock);
- }
}
#endif
void
isakmp_close()
{
- struct myaddrs *p, *next;
+ isakmp_close_sockets();
+ isakmp_free_addrs();
+}
- for (p = lcconf->myaddrs; p; p = next) {
- next = p->next;
+void
+isakmp_close_sockets()
+{
+ struct myaddrs *p;
- if (!p->addr) {
- racoon_free(p);
+ for (p = lcconf->myaddrs; p; p = p->next) {
+
+ if (!p->addr)
continue;
+
+ if (p->sock >= 0) {
+ close(p->sock);
+ p->sock = -1;
}
- close(p->sock);
+
#ifdef IKE_NAT_T
- if (p->nattsock >= 0) close(p->nattsock);
+ if (p->nattsock >= 0) {
+ close(p->nattsock);
+ p->nattsock = -1;
+ }
#endif
- racoon_free(p->addr);
+
+ }
+
+}
+
+void
+isakmp_free_addrs()
+{
+ struct myaddrs *p, *next;
+
+ for (p = lcconf->myaddrs; p; p = next) {
+ next = p->next;
+
+ if (p->addr)
+ racoon_free(p->addr);
racoon_free(p);
}
lcconf->myaddrs = NULL;
+
+}
+
+
+// close sockets for addresses that have gone away
+void
+isakmp_close_unused()
+{
+ struct myaddrs *p, *next, **prev;
+
+ prev = &(lcconf->myaddrs);
+ for (p = lcconf->myaddrs; p; p = next) {
+ next = p->next;
+ if (p->addrcount == 0) { // not in use ?
+
+ if (p->sock >= 0)
+ close(p->sock);
+
+ #ifdef IKE_NAT_T
+ if (p->nattsock >= 0)
+ close(p->nattsock);
+ #endif
+ *prev = p->next;
+ if (p->addr)
+ racoon_free(p->addr);
+ racoon_free(p);
+ } else
+ prev = &(p->next);
+ }
}
int
return -1;
}
+ if (iph2->ph1 == 0) {
+ plog(LLV_ERROR, LOCATION, NULL,
+ "internal error - attempt to re-send phase2 with no phase1 bound.\n");
+ iph2->retry_counter = -1;
+ remph2(iph2);
+ delph2(iph2);
+ return -1;
+ }
+
if (isakmp_send(iph2->ph1, iph2->sendbuf) < 0)
return -1;