ike_session_t *
ike_session_get_session (struct sockaddr_storage *local,
struct sockaddr_storage *remote,
- int alloc_if_absent)
+ int alloc_if_absent,
+ isakmp_index *optionalIndex)
{
ike_session_t *p = NULL;
ike_session_id_t id;
p->ikev1_state.active_ph1cnt, p->ikev1_state.active_ph2cnt);
continue;
}
+
+ // Skip if the spi doesn't match
+ if (optionalIndex != NULL && ike_session_getph1byindex(p, optionalIndex) == NULL) {
+ continue;
+ }
if (memcmp(&p->session_id, &id, sizeof(id)) == 0) {
plog(ASL_LEVEL_DEBUG,
return p;
} else if (is_isakmp_remote_port && memcmp(&p->session_id, &id_wop, sizeof(id_wop)) == 0) {
best_match = p;
+ } else if (optionalIndex != NULL) {
+ // If the SPI did match, this one counts as a best match
+ best_match = p;
}
}
if (best_match) {
return -1;
}
- if ((sess = ike_session_get_session(local, remote, FALSE))) {
+ if ((sess = ike_session_get_session(local, remote, FALSE, NULL))) {
return(ike_session_assert_session(sess));
}
return -1;
extern void ike_session_init (void);
extern ike_session_t * ike_session_create_session (ike_session_id_t *session_id);
extern void ike_session_release_session (ike_session_t *session);
-extern ike_session_t * ike_session_get_session (struct sockaddr_storage *, struct sockaddr_storage *, int);
+extern ike_session_t * ike_session_get_session (struct sockaddr_storage *, struct sockaddr_storage *, int, isakmp_index *);
extern u_int ike_session_get_rekey_lifetime (int, u_int);
extern void ike_session_update_mode (phase2_handle_t *iph2);
extern int ike_session_link_phase1 (ike_session_t *, phase1_handle_t *);
struct isakmp *isakmp = (struct isakmp *)msg->v;
isakmp_index *index = (isakmp_index *)isakmp;
- session = ike_session_get_session(local, remote, 1);
+ session = ike_session_get_session(local, remote, 0, index);
+ if (!session) {
+ session = ike_session_get_session(local, remote, 1, NULL);
+ }
if (!session) {
plog (ASL_LEVEL_INFO, "failed to allocate or find ike session.\n");
fatal_error(-1);
#endif
if (session == NULL) {
- session = ike_session_get_session(local, remote, 1);
+ session = ike_session_get_session(local, remote, 1, NULL);
if (!session) {
plog (ASL_LEVEL_INFO, "failed to allocate or find ike session.\n");
fatal_error(-1);
}
}
#endif
+ if (del_ph1->rmconf->natt_multiple_user &&
+ del_ph1->parent_session->is_l2tpvpn_ipsec) {
+ plog(ASL_LEVEL_DEBUG, "Ignoring IKE delete from peer for L2TP server\n");
+ break;
+ }
isakmp_ph1expire(del_ph1);
}
break;
delete->spi_size, delete->proto_id);
return 0;
}
+ if (iph1->rmconf->natt_multiple_user &&
+ iph1->parent_session->is_l2tpvpn_ipsec) {
+ plog(ASL_LEVEL_DEBUG, "Ignoring SA delete from peer for L2TP server\n");
+ break;
+ }
purge_ipsec_spi(iph1->remote, delete->proto_id,
ALIGNED_CAST(u_int32_t *)(delete + 1), num_spi, NULL, NULL); // Wcast-align fix (void*) - delete payload is aligned
break;
int error = -1;
struct isakmp_pl_n *n;
int spisiz = 0; /* see below */
- ike_session_t *sess = ike_session_get_session(local, remote, FALSE);
+ ike_session_t *sess = ike_session_get_session(local, remote, FALSE, NULL);
/* search appropreate configuration */
rmconf = getrmconf(remote);
memset (&natt, 0, sizeof (natt));
natt.sport = extract_port (iph2->ph1->remote);
flags |= SADB_X_EXT_NATT;
- if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
+ if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
+ mode == IPSEC_MODE_TRANSPORT &&
+ src->ss_family == AF_INET) {
+ flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
+ if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
+ // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
+ flags |= SADB_X_EXT_NATT_DETECTED_PEER;
+ }
+ } else if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
if (iph2->ph1->rmconf->natt_keepalive == TRUE)
flags |= SADB_X_EXT_NATT_KEEPALIVE;
} else {
- if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
- mode == IPSEC_MODE_TRANSPORT &&
- src->ss_family == AF_INET) {
- flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
- }
if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
// is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
flags |= SADB_X_EXT_NATT_DETECTED_PEER;
memset (&natt, 0, sizeof (natt));
natt.dport = extract_port (iph2->ph1->remote);
flags |= SADB_X_EXT_NATT;
- if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
+ if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
+ mode == IPSEC_MODE_TRANSPORT &&
+ src->ss_family == AF_INET) {
+ flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
+ if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
+ // is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
+ flags |= SADB_X_EXT_NATT_DETECTED_PEER;
+ }
+ } else if (iph2->ph1->natt_flags & NAT_DETECTED_ME) {
if (iph2->ph1->rmconf->natt_keepalive == TRUE)
flags |= SADB_X_EXT_NATT_KEEPALIVE;
} else {
- if (iph2->ph1->rmconf->natt_multiple_user == TRUE &&
- mode == IPSEC_MODE_TRANSPORT &&
- dst->ss_family == AF_INET) {
- flags |= SADB_X_EXT_NATT_MULTIPLEUSERS;
- }
if (iph2->ph1->natt_flags & NAT_DETECTED_PEER) {
// is mutually exclusive with SADB_X_EXT_NATT_KEEPALIVE
flags |= SADB_X_EXT_NATT_DETECTED_PEER;
}
if (session == NULL)
- session = ike_session_get_session(iph2->src, iph2->dst, 1);
+ session = ike_session_get_session(iph2->src, iph2->dst, 1, NULL);
if (session == NULL)
fatal_error(-1);