osmo-epdg: Use the new UE/db object

Save the state of the UE into the UE object in the database.
This commit is contained in:
Alexander Couzens 2024-02-17 00:26:19 +01:00
parent 6f3e8f5ecd
commit aaba569495
5 changed files with 124 additions and 12 deletions

View File

@ -27,6 +27,7 @@
#include "osmo_epdg_plugin.h"
#include "osmo_epdg_listener.h"
#include "osmo_epdg_db.h"
#include "osmo_epdg_utils.h"
typedef struct private_osmo_epdg_listener_t private_osmo_epdg_listener_t;
@ -39,8 +40,8 @@ struct private_osmo_epdg_listener_t {
* Public osmo_epdg_listener_t interface.
*/
osmo_epdg_listener_t public;
osmo_epdg_gsup_client_t *gsup;
osmo_epdg_db_t *db;
};
METHOD(listener_t, eap_authorize, bool,
@ -48,6 +49,7 @@ METHOD(listener_t, eap_authorize, bool,
identification_t *id, bool final, bool *success)
{
char imsi[16] = {0};
osmo_epdg_ue_t *ue = NULL;
if (!id)
{
@ -60,10 +62,18 @@ METHOD(listener_t, eap_authorize, bool,
goto err;
}
ue = this->db->create_subscriber(this->db, ike_sa);
if (!ue)
{
DBG1(DBG_NET, "epdg: authorize: Could not create subscriber via db! Rejecting.");
goto err;
}
osmo_epdg_gsup_response_t *resp = this->gsup->update_location(this->gsup, imsi, OSMO_GSUP_CN_DOMAIN_PS);
if (!resp)
{
DBG1(DBG_NET, "epdg: GSUP: couldn't send Update Location.");
this->db->remove_subscriber(this->db, imsi);
goto err;
}
@ -72,11 +82,18 @@ METHOD(listener_t, eap_authorize, bool,
DBG1(DBG_NET, "epdg_listener: Update Location Error! Cause: %02x", resp->gsup.cause);
goto err;
}
ue->set_state(ue, UE_LOCATION_UPDATED);
ue->put(ue);
return TRUE;
err:
*success = FALSE;
if (ue)
{
ue->set_state(ue, UE_FAIL);
ue->put(ue);
}
/* keep still subscribed */
return TRUE;
}
@ -88,6 +105,12 @@ METHOD(listener_t, authorize, bool,
int ret;
identification_t* imsi_id;
char imsi[16] = {0};
osmo_epdg_ue_t *ue = NULL;
host_t *address = NULL;
struct osmo_gsup_pdp_info *pdp_info;
osmo_epdg_gsup_response_t *resp = NULL;
DBG1(DBG_NET, "Authorized: uniq 0x%08x, name %s final: %d, eap: %d!",
ike_sa->get_unique_id(ike_sa),
ike_sa->get_name(ike_sa),
@ -112,7 +135,14 @@ METHOD(listener_t, authorize, bool,
goto err;
}
osmo_epdg_gsup_response_t *resp = this->gsup->tunnel_request(this->gsup, imsi);
ue = this->db->get_subscriber(this->db, imsi);
if (!ue)
{
DBG1(DBG_NET, "epdg: authorize: Can't find match UE for imsi %s via EAP identity.", imsi);
}
ue->set_state(ue, UE_WAIT_TUNNEL);
resp = this->gsup->tunnel_request(this->gsup, imsi);
if (!resp)
{
DBG1(DBG_NET, "epdg_listener: Tunnel Request: GSUP: couldn't send.");
@ -130,8 +160,53 @@ METHOD(listener_t, authorize, bool,
goto err;
}
/* validate Tunnel Response */
if ((resp->gsup.num_pdp_infos != 1) ||
(!resp->gsup.pdp_infos[0].have_info) ||
(resp->gsup.pdp_infos[0].pdp_type_org != PDP_TYPE_ORG_IETF) ||
(resp->gsup.pdp_infos[0].pdp_type_nr != PDP_TYPE_N_IETF_IPv4))
{
DBG1(DBG_NET, "epdg_listener: Tunnel Response: IMSI %s: received incomplete message/wrong content", imsi);
goto err;
}
pdp_info = &resp->gsup.pdp_infos[0];
/* if the sa_family is set, the address is valid */
if (pdp_info->pdp_address[0].u.sa.sa_family != AF_INET)
{
DBG1(DBG_NET, "epdg_listener: Tunnel Response: IMSI %s: received wrong PDP info", imsi);
goto err;
}
address = host_create_from_sockaddr(&pdp_info->pdp_address[0].u.sa);
if (!address)
{
DBG1(DBG_NET, "epdg_listener: Tunnel Response: IMSI %s: couldn't convert PDP info to host_address", imsi);
goto err;
}
ue->set_address(ue, address);
ue->set_state(ue, UE_TUNNEL_READY);
ue->put(ue);
address->destroy(address);
free(resp);
return TRUE;
err:
if (resp)
{
free(resp);
}
if (ue)
{
ue->set_state(ue, UE_FAIL);
ue->put(ue);
}
DESTROY_IF(address);
*success = FALSE;
/* keep still subscribed */
return TRUE;
@ -146,7 +221,7 @@ METHOD(osmo_epdg_listener_t, destroy, void,
/**
* See header
*/
osmo_epdg_listener_t *osmo_epdg_listener_create(osmo_epdg_gsup_client_t *gsup)
osmo_epdg_listener_t *osmo_epdg_listener_create(osmo_epdg_db_t *db, osmo_epdg_gsup_client_t *gsup)
{
private_osmo_epdg_listener_t *this;
@ -159,6 +234,7 @@ osmo_epdg_listener_t *osmo_epdg_listener_create(osmo_epdg_gsup_client_t *gsup)
.destroy = _destroy,
},
.gsup = gsup,
.db = db,
);
return &this->public;

View File

@ -27,6 +27,7 @@
#define OSMO_EPDG_LISTENER_H_
#include <bus/listeners/listener.h>
#include "osmo_epdg_db.h"
#include "gsup_client.h"
typedef struct osmo_epdg_listener_t osmo_epdg_listener_t;
@ -50,6 +51,6 @@ struct osmo_epdg_listener_t {
/**
* Create a osmo_epdg_listener instance.
*/
osmo_epdg_listener_t *osmo_epdg_listener_create(osmo_epdg_gsup_client_t *gsup);
osmo_epdg_listener_t *osmo_epdg_listener_create(osmo_epdg_db_t *db, osmo_epdg_gsup_client_t *gsup);
#endif /** OSMO_EPDG_LISTENER_H_ @}*/

View File

@ -40,8 +40,8 @@ struct private_osmo_epdg_t {
* SIM AKA provider
*/
osmo_epdg_provider_t *provider;
osmo_epdg_listener_t *listener;
osmo_epdg_db_t *db;
};
METHOD(plugin_t, get_name, char*,
@ -56,12 +56,14 @@ static bool register_functions(private_osmo_epdg_t *this,
if (reg)
{
osmo_epdg_gsup_client_t *gsup = osmo_epdg_gsup_client_create("tcp://127.0.0.1:4222");
this->provider = osmo_epdg_provider_create(gsup);
this->listener = osmo_epdg_listener_create(gsup);
this->db = osmo_epdg_db_create();
this->provider = osmo_epdg_provider_create(this->db, gsup);
this->listener = osmo_epdg_listener_create(this->db, gsup);
charon->bus->add_listener(charon->bus, &this->listener->listener);
charon->attributes->add_provider(charon->attributes, &this->provider->attribute);
return TRUE;
}
if (this->listener)
{
charon->bus->remove_listener(charon->bus, &this->listener->listener);
@ -69,6 +71,10 @@ static bool register_functions(private_osmo_epdg_t *this,
charon->attributes->remove_provider(charon->attributes, &this->provider->attribute);
this->provider->destroy(this->provider);
this->provider = NULL;
this->listener->destroy(this->listener);
this->listener = NULL;
this->db->destroy(this->db);
this->db = NULL;
return TRUE;
}

View File

@ -19,6 +19,8 @@
#include "osmo_epdg_provider.h"
#include "osmo_epdg_utils.h"
#include "gsup_client.h"
#include "osmo_epdg_db.h"
#include "osmo_epdg_ue.h"
#include <daemon.h>
#include <credentials/keys/shared_key.h>
@ -46,6 +48,8 @@ struct private_osmo_epdg_provider_t {
osmo_epdg_provider_t public;
osmo_epdg_gsup_client_t *gsup;
osmo_epdg_db_t *db;
};
/**
@ -142,9 +146,18 @@ METHOD(attribute_provider_t, acquire_address, host_t*,
private_osmo_epdg_provider_t *this, linked_list_t *pools, ike_sa_t *ike_sa,
host_t *requested)
{
osmo_epdg_ue_t *ue = this->db->get_subscriber_ike(this->db, ike_sa);
host_t *address = NULL;
/* TODO: check if we want to limit the pool here as well to "epdg" similar what dhcp does */
if (!ue)
{
DBG1(DBG_NET, "epdg_provider: acquire_address: Failed to get the UE by IKE");
return NULL;
}
address = ue->get_address(ue);
ue->put(ue);
address = host_create_from_string_and_family("10.45.0.1", AF_INET, 0);
return address;
}
@ -152,7 +165,21 @@ METHOD(attribute_provider_t, release_address, bool,
private_osmo_epdg_provider_t *this, linked_list_t *pools, host_t *address,
ike_sa_t *ike_sa)
{
return TRUE;
osmo_epdg_ue_t *ue = this->db->get_subscriber_ike(this->db, ike_sa);
host_t *ue_address = ue->get_address(ue);
bool found = FALSE;
if (!ue)
{
DBG1(DBG_NET, "epdg_provider: release_address: Failed to get the UE by IKE");
return FALSE;
}
found = address->equals(address, ue_address);
ue_address->destroy(ue_address);
ue->put(ue);
return found;
}
METHOD(attribute_provider_t, create_attribute_enumerator, enumerator_t*,
@ -172,7 +199,7 @@ METHOD(osmo_epdg_provider_t, destroy, void,
/**
* See header
*/
osmo_epdg_provider_t *osmo_epdg_provider_create(osmo_epdg_gsup_client_t *gsup)
osmo_epdg_provider_t *osmo_epdg_provider_create(osmo_epdg_db_t *db, osmo_epdg_gsup_client_t *gsup)
{
private_osmo_epdg_provider_t *this;
@ -194,6 +221,7 @@ osmo_epdg_provider_t *osmo_epdg_provider_create(osmo_epdg_gsup_client_t *gsup)
},
.destroy = _destroy,
},
.db = db,
.gsup = gsup,
);

View File

@ -28,6 +28,7 @@
#include <simaka_provider.h>
#include <attributes/attribute_provider.h>
#include "osmo_epdg_db.h"
#include "gsup_client.h"
typedef struct osmo_epdg_provider_t osmo_epdg_provider_t;
@ -57,6 +58,6 @@ struct osmo_epdg_provider_t {
/**
* Create a osmo_epdg_provider instance.
*/
osmo_epdg_provider_t *osmo_epdg_provider_create(osmo_epdg_gsup_client_t *gsup);
osmo_epdg_provider_t *osmo_epdg_provider_create(osmo_epdg_db_t *db, osmo_epdg_gsup_client_t *gsup);
#endif /** OSMO_EPDG_PROVIDER_H_ @}*/