Hi, in the error case ikev2_msg_send the accesses the sa before checking for NULL. The diff adds explicit checks in those cases. If sendtofrom fails for any other reason than EADDRNOTAVAIL and sa is not NULL we should continue instead of returning (-1) so that the error is handled with retransmission.
ok? Index: ikev2_msg.c =================================================================== RCS file: /mount/openbsd/cvs/src/sbin/iked/ikev2_msg.c,v retrieving revision 1.58 diff -u -p -r1.58 ikev2_msg.c --- ikev2_msg.c 13 Nov 2019 12:24:40 -0000 1.58 +++ ikev2_msg.c 14 Nov 2019 15:37:11 -0000 @@ -339,15 +339,20 @@ ikev2_msg_send(struct iked *env, struct (struct sockaddr *)&msg->msg_peer, msg->msg_peerlen, (struct sockaddr *)&msg->msg_local, msg->msg_locallen) == -1) { if (errno == EADDRNOTAVAIL) { - sa_state(env, msg->msg_sa, IKEV2_STATE_CLOSING); - timer_del(env, &msg->msg_sa->sa_timer); - timer_set(env, &msg->msg_sa->sa_timer, - ikev2_ike_sa_timeout, msg->msg_sa); - timer_add(env, &msg->msg_sa->sa_timer, - IKED_IKE_SA_DELETE_TIMEOUT); + if (sa != NULL) { + sa_state(env, sa, IKEV2_STATE_CLOSING); + timer_del(env, &sa->sa_timer); + timer_set(env, &sa->sa_timer, + ikev2_ike_sa_timeout, sa); + timer_add(env, &sa->sa_timer, + IKED_IKE_SA_DELETE_TIMEOUT); + } + log_warn("%s: sendtofrom", __func__); + return (-1); } log_warn("%s: sendtofrom", __func__); - return (-1); + if (!sa) + return (-1); } if (!sa)