diff options
author | Hakan Olsson <ho@cvs.openbsd.org> | 2004-06-21 23:27:11 +0000 |
---|---|---|
committer | Hakan Olsson <ho@cvs.openbsd.org> | 2004-06-21 23:27:11 +0000 |
commit | 19361778431fa0cc1cf73abf7ffecf3142793f9b (patch) | |
tree | bd35225f6031d82bef0fce4af0afd5dfd17fc49e /sbin/isakmpd/udp_encap.c | |
parent | c35a3cc1f50889911a74c83ea50c365a41f09b11 (diff) |
Implement NAT-T keepalive messages.
Diffstat (limited to 'sbin/isakmpd/udp_encap.c')
-rw-r--r-- | sbin/isakmpd/udp_encap.c | 45 |
1 files changed, 28 insertions, 17 deletions
diff --git a/sbin/isakmpd/udp_encap.c b/sbin/isakmpd/udp_encap.c index d6cebf473f5..e9ef4c0a3e7 100644 --- a/sbin/isakmpd/udp_encap.c +++ b/sbin/isakmpd/udp_encap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: udp_encap.c,v 1.2 2004/06/21 13:09:01 ho Exp $ */ +/* $OpenBSD: udp_encap.c,v 1.3 2004/06/21 23:27:10 ho Exp $ */ /* * Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved. @@ -417,27 +417,38 @@ udp_encap_handle_message(struct transport *t) message_recv (msg); } -/* Physically send the message MSG over its associated transport. */ +/* + * Physically send the message MSG over its associated transport. + * Special: if 'msg' is NULL, send a NAT-T keepalive message. + */ static int udp_encap_send_message(struct message *msg, struct transport *t) { struct udp_transport *u = (struct udp_transport *)t; struct msghdr m; - struct iovec *new_iov; + struct iovec *new_iov = 0, keepalive; ssize_t n; u_int32_t marker = 0; /* NULL-ESP Marker */ - /* Construct new iov array, prefixing NULL-ESP Marker. */ - new_iov = (struct iovec *)calloc (msg->iovlen + 1, sizeof *new_iov); - if (!new_iov) { - log_error ("udp_encap_send_message: calloc (%lu, %lu) failed", - (unsigned long)msg->iovlen + 1, - (unsigned long)sizeof *new_iov); - return -1; + if (msg) { + /* Construct new iov array, prefixing NULL-ESP Marker. */ + new_iov = (struct iovec *)calloc (msg->iovlen + 1, + sizeof *new_iov); + if (!new_iov) { + log_error ("udp_encap_send_message: " + "calloc (%lu, %lu) failed", + (unsigned long)msg->iovlen + 1, + (unsigned long)sizeof *new_iov); + return -1; + } + new_iov[0].iov_base = ▮ + new_iov[0].iov_len = IPSEC_SPI_SIZE; + memcpy (new_iov + 1, msg->iov, msg->iovlen * sizeof *new_iov); + } else { + marker = ~marker; + keepalive.iov_base = ▮ + keepalive.iov_len = 1; } - new_iov[0].iov_base = ▮ - new_iov[0].iov_len = IPSEC_SPI_SIZE; - memcpy (new_iov + 1, msg->iov, msg->iovlen * sizeof *new_iov); /* * Sending on connected sockets requires that no destination address is @@ -445,18 +456,18 @@ udp_encap_send_message(struct message *msg, struct transport *t) */ m.msg_name = (caddr_t)u->dst; m.msg_namelen = sysdep_sa_len (u->dst); - m.msg_iov = new_iov; - m.msg_iovlen = msg->iovlen + 1; + m.msg_iov = msg ? new_iov : &keepalive; + m.msg_iovlen = msg ? msg->iovlen + 1 : 1; m.msg_control = 0; m.msg_controllen = 0; m.msg_flags = 0; n = sendmsg (u->s, &m, 0); + if (msg) + free (new_iov); if (n == -1) { /* XXX We should check whether the address has gone away */ log_error ("sendmsg (%d, %p, %d)", u->s, &m, 0); - free (new_iov); return -1; } - free (new_iov); return 0; } |