diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-04-13 07:04:10 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2017-04-13 07:04:10 +0000 |
commit | 6370a5ccd60fbe7c6a6a804f6f4ccc77dc2dde81 (patch) | |
tree | a68d93628ee47c4722dc2f0ee1bc586142d06810 | |
parent | f9008673f7067d35956794a87d8185a8c8628749 (diff) |
Add a NAT-T keepalive timer in case we are behind a NAT gateway.
See RFC 5996, section 2.23, NAT Traversal:
In the case of a mismatching NAT_DETECTION_DESTINATION_IP hash, it
means that the system receiving the NAT_DETECTION_DESTINATION_IP
payload is behind a NAT and that system SHOULD start sending
keepalive packets as defined in [UDPENCAPS].
With markus@, ok reyk@
-rw-r--r-- | sbin/iked/config.c | 3 | ||||
-rw-r--r-- | sbin/iked/iked.h | 6 | ||||
-rw-r--r-- | sbin/iked/ikev2.c | 37 | ||||
-rw-r--r-- | sbin/iked/ikev2_pld.c | 5 |
4 files changed, 47 insertions, 4 deletions
diff --git a/sbin/iked/config.c b/sbin/iked/config.c index d24da1445c9..590e4d7f4da 100644 --- a/sbin/iked/config.c +++ b/sbin/iked/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.47 2017/03/27 10:43:53 mikeb Exp $ */ +/* $OpenBSD: config.c,v 1.48 2017/04/13 07:04:09 patrick Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -97,6 +97,7 @@ void config_free_sa(struct iked *env, struct iked_sa *sa) { timer_del(env, &sa->sa_timer); + timer_del(env, &sa->sa_keepalive); timer_del(env, &sa->sa_rekey); config_free_proposals(&sa->sa_proposals, 0); diff --git a/sbin/iked/iked.h b/sbin/iked/iked.h index 25e81ea34a8..7e77d206f77 100644 --- a/sbin/iked/iked.h +++ b/sbin/iked/iked.h @@ -1,4 +1,4 @@ -/* $OpenBSD: iked.h,v 1.113 2017/03/27 17:17:49 mikeb Exp $ */ +/* $OpenBSD: iked.h,v 1.114 2017/04/13 07:04:09 patrick Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -376,6 +376,7 @@ struct iked_sa { int sa_natt; /* for IKE messages */ int sa_udpencap; /* for pfkey */ + int sa_usekeepalive;/* NAT-T keepalive */ int sa_state; unsigned int sa_stateflags; @@ -446,6 +447,9 @@ struct iked_sa { #define IKED_IKE_SA_DELETE_TIMEOUT 120 /* 2 minutes */ #define IKED_IKE_SA_ALIVE_TIMEOUT 60 /* 1 minute */ + struct iked_timer sa_keepalive; /* keepalive timer */ +#define IKED_IKE_SA_KEEPALIVE_TIMEOUT 20 + struct iked_timer sa_rekey; /* rekey timeout */ struct iked_msgqueue sa_requests; /* request queue */ diff --git a/sbin/iked/ikev2.c b/sbin/iked/ikev2.c index cd8b0d89b95..078886ce604 100644 --- a/sbin/iked/ikev2.c +++ b/sbin/iked/ikev2.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ikev2.c,v 1.152 2017/03/30 15:48:30 patrick Exp $ */ +/* $OpenBSD: ikev2.c,v 1.153 2017/04/13 07:04:09 patrick Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -89,6 +89,7 @@ void ikev2_ike_sa_rekey_timeout(struct iked *, void *); void ikev2_ike_sa_rekey_schedule(struct iked *, struct iked_sa *); void ikev2_ike_sa_timeout(struct iked *env, void *); void ikev2_ike_sa_alive(struct iked *, void *); +void ikev2_ike_sa_keepalive(struct iked *, void *); int ikev2_sa_initiator(struct iked *, struct iked_sa *, struct iked_sa *, struct iked_message *); @@ -1200,6 +1201,10 @@ ikev2_init_done(struct iked *env, struct iked_sa *sa) timer_del(env, &sa->sa_timer); timer_set(env, &sa->sa_timer, ikev2_ike_sa_alive, sa); timer_add(env, &sa->sa_timer, IKED_IKE_SA_ALIVE_TIMEOUT); + timer_set(env, &sa->sa_keepalive, ikev2_ike_sa_keepalive, sa); + if (sa->sa_usekeepalive) + timer_add(env, &sa->sa_keepalive, + IKED_IKE_SA_KEEPALIVE_TIMEOUT); timer_set(env, &sa->sa_rekey, ikev2_ike_sa_rekey, sa); if (sa->sa_policy->pol_rekey) ikev2_ike_sa_rekey_schedule(env, sa); @@ -2473,6 +2478,10 @@ ikev2_resp_ike_auth(struct iked *env, struct iked_sa *sa) timer_del(env, &sa->sa_timer); timer_set(env, &sa->sa_timer, ikev2_ike_sa_alive, sa); timer_add(env, &sa->sa_timer, IKED_IKE_SA_ALIVE_TIMEOUT); + timer_set(env, &sa->sa_keepalive, ikev2_ike_sa_keepalive, sa); + if (sa->sa_usekeepalive) + timer_add(env, &sa->sa_keepalive, + IKED_IKE_SA_KEEPALIVE_TIMEOUT); timer_set(env, &sa->sa_rekey, ikev2_ike_sa_rekey, sa); if (sa->sa_policy->pol_rekey) ikev2_ike_sa_rekey_schedule(env, sa); @@ -3142,6 +3151,7 @@ ikev2_ikesa_enable(struct iked *env, struct iked_sa *sa, struct iked_sa *nsa) nsa->sa_fd = sa->sa_fd; nsa->sa_natt = sa->sa_natt; nsa->sa_udpencap = sa->sa_udpencap; + nsa->sa_usekeepalive = sa->sa_usekeepalive; /* Transfer old addresses */ memcpy(&nsa->sa_local, &sa->sa_local, sizeof(nsa->sa_local)); @@ -3226,6 +3236,10 @@ ikev2_ikesa_enable(struct iked *env, struct iked_sa *sa, struct iked_sa *nsa) sa_state(env, nsa, IKEV2_STATE_ESTABLISHED); timer_set(env, &nsa->sa_timer, ikev2_ike_sa_alive, nsa); timer_add(env, &nsa->sa_timer, IKED_IKE_SA_ALIVE_TIMEOUT); + timer_set(env, &nsa->sa_keepalive, ikev2_ike_sa_keepalive, nsa); + if (nsa->sa_usekeepalive) + timer_add(env, &nsa->sa_keepalive, + IKED_IKE_SA_KEEPALIVE_TIMEOUT); timer_set(env, &nsa->sa_rekey, ikev2_ike_sa_rekey, nsa); if (nsa->sa_policy->pol_rekey) ikev2_ike_sa_rekey_schedule(env, nsa); @@ -3234,6 +3248,7 @@ ikev2_ikesa_enable(struct iked *env, struct iked_sa *sa, struct iked_sa *nsa) /* unregister DPD keep alive timer & rekey first */ if (sa->sa_state == IKEV2_STATE_ESTABLISHED) { timer_del(env, &sa->sa_rekey); + timer_del(env, &sa->sa_keepalive); timer_del(env, &sa->sa_timer); } @@ -3626,6 +3641,26 @@ ikev2_ike_sa_alive(struct iked *env, void *arg) timer_add(env, &sa->sa_timer, IKED_IKE_SA_ALIVE_TIMEOUT); } +void +ikev2_ike_sa_keepalive(struct iked *env, void *arg) +{ + struct iked_sa *sa = arg; + uint8_t marker = 0xff; + + if (sendtofrom(sa->sa_fd, &marker, sizeof(marker), 0, + (struct sockaddr *)&sa->sa_peer.addr, sa->sa_peer.addr.ss_len, + (struct sockaddr *)&sa->sa_local.addr, sa->sa_local.addr.ss_len) + == -1) + log_warn("%s: sendtofrom: peer %s local %s", __func__, + print_host((struct sockaddr *)&sa->sa_peer.addr, NULL, 0), + print_host((struct sockaddr *)&sa->sa_local.addr, NULL, 0)); + else + log_debug("%s: peer %s local %s", __func__, + print_host((struct sockaddr *)&sa->sa_peer.addr, NULL, 0), + print_host((struct sockaddr *)&sa->sa_local.addr, NULL, 0)); + timer_add(env, &sa->sa_keepalive, IKED_IKE_SA_KEEPALIVE_TIMEOUT); +} + int ikev2_send_informational(struct iked *env, struct iked_message *msg) { diff --git a/sbin/iked/ikev2_pld.c b/sbin/iked/ikev2_pld.c index 86086e56ca4..5724520f696 100644 --- a/sbin/iked/ikev2_pld.c +++ b/sbin/iked/ikev2_pld.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ikev2_pld.c,v 1.61 2017/03/27 17:17:49 mikeb Exp $ */ +/* $OpenBSD: ikev2_pld.c,v 1.62 2017/04/13 07:04:09 patrick Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter <reyk@openbsd.org> @@ -1148,6 +1148,9 @@ ikev2_pld_notify(struct iked *env, struct ikev2_payload *pld, */ if (msg->msg_sa != NULL) msg->msg_sa->sa_udpencap = 1; + /* Send keepalive, since we are behind a NAT-gw */ + if (type == IKEV2_N_NAT_DETECTION_DESTINATION_IP) + msg->msg_sa->sa_usekeepalive = 1; } print_hex(md, 0, sizeof(md)); break; |