implement periodic Location Update expiry in the VLR

Remove subscribers which fail to send periodic Location Updates from the
list of subscribers known to the VLR. This complements the IMSI detach
procedure: periodic LU expiry triggers an implicit IMSI detach.

Expired subscribers are purged from a periodic timer which iterates
over all subscribers once per minute.

Subscribers with an active connection do not expire. This is controlled
by the subscriber conn FSM which sets a subscriber's the LU expiry timeout
value to GSM_SUBSCRIBER_NO_EXPIRATION while a connection is active.

Add support for fake time with osmo_clock_gettime() to msc_vlr tests.

This functionality existed in OpenBSC but was lost during the nitb split.
This code took some inspiration from the OpenBSC implementation.

Related: OS#1976
Change-Id: Iebdee8b12d22acfcfb265ee41e71cfc8d9eb3ba9
This commit is contained in:
Stefan Sperling 2018-05-15 14:48:04 +02:00 committed by Neels Hofmeyr
parent 2d95ab67d1
commit defc3c8caf
9 changed files with 264 additions and 3 deletions

View File

@ -17,8 +17,6 @@
#define GSM_SUBSCRIBER_FIRST_CONTACT 0x00000001
/* gprs_sgsn.h defines additional flags including and above bit 16 (0x10000) */
#define GSM_SUBSCRIBER_NO_EXPIRATION 0x0
enum gsm_subscriber_field {
GSM_SUBSCRIBER_IMSI,
GSM_SUBSCRIBER_TMSI,

View File

@ -20,6 +20,9 @@
struct log_target;
#define VLR_SUBSCRIBER_NO_EXPIRATION 0
#define VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL 60 /* in seconds */
/* from 3s to 10s */
#define GSM_29002_TIMER_S 10
/* from 15s to 30s */
@ -148,6 +151,7 @@ struct vlr_subscr {
struct osmo_fsm_inst *proc_arq_fsm;
bool lu_complete;
time_t expire_lu;
void *msc_conn_ref;
@ -237,6 +241,7 @@ struct vlr_instance {
struct llist_head operations;
struct gsup_client *gsup_client;
struct vlr_ops ops;
struct osmo_timer_list lu_expire_timer;
struct {
bool retrieve_imeisv_early;
bool retrieve_imeisv_ciphered;
@ -379,6 +384,7 @@ void vlr_subscr_cancel_attach_fsm(struct vlr_subscr *vsub,
enum osmo_fsm_term_cause fsm_cause,
uint8_t gsm48_cause);
void vlr_subscr_enable_expire_lu(struct vlr_subscr *vsub);
/* Process Acccess Request FSM */

View File

@ -202,6 +202,15 @@ static bool subscr_conn_fsm_has_active_transactions(struct osmo_fsm_inst *fi)
static void subscr_conn_fsm_accepted_enter(struct osmo_fsm_inst *fi, uint32_t prev_state)
{
struct gsm_subscriber_connection *conn = fi->priv;
/* Stop Location Update expiry for this subscriber. While the subscriber
* has an open connection the LU expiry timer must remain disabled.
* Otherwise we would kick the subscriber off the network when the timer
* expires e.g. during a long phone call.
* The LU expiry timer will restart once the connection is closed. */
conn->vsub->expire_lu = VLR_SUBSCRIBER_NO_EXPIRATION;
if (!subscr_conn_fsm_has_active_transactions(fi))
osmo_fsm_inst_dispatch(fi, SUBSCR_CONN_E_UNUSED, NULL);
}
@ -278,6 +287,12 @@ static void subscr_conn_fsm_releasing_onenter(struct osmo_fsm_inst *fi, uint32_t
/* Cancel all VLR FSMs, if any */
vlr_subscr_cancel_attach_fsm(conn->vsub, OSMO_FSM_TERM_ERROR, GSM48_REJECT_CONGESTION);
if (conn->vsub) {
/* The subscriber has no active connection anymore.
* Restart the periodic Location Update expiry timer for this subscriber. */
vlr_subscr_enable_expire_lu(conn->vsub);
}
/* If we're closing in a middle of a trans, we need to clean up */
trans_conn_closed(conn);

View File

@ -22,6 +22,7 @@
#include <osmocom/core/linuxlist.h>
#include <osmocom/core/fsm.h>
#include <osmocom/core/utils.h>
#include <osmocom/core/timer.h>
#include <osmocom/gsm/protocol/gsm_04_08_gprs.h>
#include <osmocom/gsm/gsup.h>
#include <osmocom/gsm/apn.h>
@ -460,6 +461,50 @@ int vlr_subscr_changed(struct vlr_subscr *vsub)
return 0;
}
void vlr_subscr_enable_expire_lu(struct vlr_subscr *vsub)
{
struct gsm_network *net = vsub->vlr->user_ctx; /* XXX move t3212 into struct vlr_instance? */
struct timespec now;
/* The T3212 timeout value field is coded as the binary representation of the timeout
* value for periodic updating in decihours. Mark the subscriber as inactive if it missed
* two consecutive location updates. Timeout is twice the t3212 value plus one minute. */
if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) == 0) {
vsub->expire_lu = now.tv_sec + (net->t3212 * 60 * 6 * 2) + 60;
} else {
LOGP(DVLR, LOGL_ERROR,
"%s: Could not enable Location Update expiry: unable to read current time\n", vlr_subscr_name(vsub));
/* Disable LU expiry for this subscriber. This subscriber will only be freed after an explicit IMSI detach. */
vsub->expire_lu = VLR_SUBSCRIBER_NO_EXPIRATION;
}
}
void vlr_subscr_expire_lu(void *data)
{
struct vlr_instance *vlr = data;
struct vlr_subscr *vsub, *vsub_tmp;
struct timespec now;
if (llist_empty(&vlr->subscribers))
goto done;
if (osmo_clock_gettime(CLOCK_MONOTONIC, &now) != 0) {
LOGP(DVLR, LOGL_ERROR, "Skipping Location Update expiry: Could not read current time\n");
goto done;
}
llist_for_each_entry_safe(vsub, vsub_tmp, &vlr->subscribers, list) {
if (vsub->expire_lu == VLR_SUBSCRIBER_NO_EXPIRATION || vsub->expire_lu > now.tv_sec)
continue;
LOGP(DVLR, LOGL_DEBUG, "%s: Location Update expired\n", vlr_subscr_name(vsub));
vlr_subscr_rx_imsi_detach(vsub);
}
done:
osmo_timer_schedule(&vlr->lu_expire_timer, VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL, 0);
}
/***********************************************************************
* PDP context data
***********************************************************************/
@ -1093,12 +1138,14 @@ bool vlr_subscr_expire(struct vlr_subscr *vsub)
return false;
}
/* See TS 23.012 version 9.10.0 4.3.2.1 "Process Detach_IMSI_VLR" */
int vlr_subscr_rx_imsi_detach(struct vlr_subscr *vsub)
{
/* paranoia: should any LU or PARQ FSMs still be running, stop them. */
vlr_subscr_cancel_attach_fsm(vsub, OSMO_FSM_TERM_ERROR, GSM48_REJECT_CONGESTION);
vsub->imsi_detached_flag = true;
vsub->expire_lu = VLR_SUBSCRIBER_NO_EXPIRATION;
/* balancing the get from vlr_lu_compl_fsm_success() */
vlr_subscr_expire(vsub);
@ -1165,6 +1212,8 @@ int vlr_start(const char *gsup_unit_name, struct vlr_instance *vlr,
return -ENOMEM;
vlr->gsup_client->data = vlr;
osmo_timer_setup(&vlr->lu_expire_timer, vlr_subscr_expire_lu, vlr);
osmo_timer_schedule(&vlr->lu_expire_timer, VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL, 0);
return 0;
}

View File

@ -356,7 +356,7 @@ static void vlr_lu_compl_fsm_success(struct osmo_fsm_inst *fi)
struct vlr_subscr *vsub = lcvp->vsub;
if (!vsub->lu_complete) {
vsub->lu_complete = true;
/* Balanced by vlr_subscr_rx_imsi_detach() */
/* Balanced by vlr_subscr_expire() */
vlr_subscr_get(vsub);
}
_vlr_lu_compl_fsm_done(fi, VLR_FSM_RESULT_SUCCESS, 0);

View File

@ -917,6 +917,64 @@ static void test_no_authen_imeisv_tmsi_imei()
comment_end();
}
static void test_no_authen_subscr_expire()
{
struct vlr_subscr *vsub;
const char *imsi = "901700000004620";
/* No auth only works on GERAN */
rx_from_ran = RAN_GERAN_A;
comment_start();
fake_time_start();
/* The test framework has already started the VLR before fake time was active.
* Manually schedule this timeout in fake time. */
osmo_timer_del(&net->vlr->lu_expire_timer);
osmo_timer_schedule(&net->vlr->lu_expire_timer, VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL, 0);
/* Let the LU expiration timer tick once */
fake_time_passes(VLR_SUBSCRIBER_LU_EXPIRATION_INTERVAL + 1, 0);
btw("Location Update request causes a GSUP LU request to HLR");
lu_result_sent = RES_NONE;
gsup_expect_tx("04010809710000004026f0");
ms_sends_msg("050802008168000130089910070000006402");
OSMO_ASSERT(gsup_tx_confirmed);
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT");
gsup_rx("10010809710000004026f00804036470f1",
"12010809710000004026f0");
VERBOSE_ASSERT(lu_result_sent, == RES_NONE, "%d");
btw("HLR also sends GSUP _UPDATE_LOCATION_RESULT");
expect_bssap_clear();
gsup_rx("06010809710000004026f0", NULL);
btw("LU was successful, and the conn has already been closed");
VERBOSE_ASSERT(lu_result_sent, == RES_ACCEPT, "%d");
VERBOSE_ASSERT(bssap_clear_sent, == true, "%d");
bss_sends_clear_complete();
EXPECT_CONN_COUNT(0);
vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
OSMO_ASSERT(vsub);
vlr_subscr_put(vsub);
/* Let T3212 (periodic Location update timer) expire */
fake_time_passes((net->t3212 * 60 * 6 * 2) + 60*4, 0);
/* The subscriber should now be gone. */
vsub = vlr_subscr_find_by_imsi(net->vlr, imsi);
OSMO_ASSERT(vsub == NULL);
EXPECT_CONN_COUNT(0);
clear_vlr();
comment_end();
}
msc_vlr_test_func_t msc_vlr_tests[] = {
test_no_authen,
@ -927,5 +985,6 @@ msc_vlr_test_func_t msc_vlr_tests[] = {
test_no_authen_imeisv_imei,
test_no_authen_imeisv_tmsi,
test_no_authen_imeisv_tmsi_imei,
test_no_authen_subscr_expire,
NULL
};

View File

@ -2270,6 +2270,132 @@ DMM Subscr_Conn{SUBSCR_CONN_S_RELEASED}: Deallocated
full talloc report on 'msgb' (total 0 bytes in 1 blocks)
talloc_total_blocks(tall_bsc_ctx) == 12
===== test_no_authen_subscr_expire
- Total time passed: 0.000000 s
- Total time passed: 61.000000 s
- Location Update request causes a GSUP LU request to HLR
MSC <--RAN_GERAN_A-- MS: GSM48_MT_MM_LOC_UPD_REQUEST
new conn
DMM Subscr_Conn{SUBSCR_CONN_S_NEW}: Allocated
DREF unknown: MSC conn use + compl_l3 == 1 (0x1: compl_l3)
DRLL Dispatching 04.08 message GSM48_MT_MM_LOC_UPD_REQUEST (0x5:0x8)
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Updated ID
DMM LOCATION UPDATING REQUEST: MI(IMSI)=901700000004620 type=IMSI ATTACH
DMM LU/new-LAC: 1/23
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Allocated
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: is child of Subscr_Conn(LU:901700000004620)
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: rev=GSM net=GERAN (no Auth)
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: Received Event VLR_ULA_E_UPDATE_LA
DREF VLR subscr unknown usage increases to: 1
DVLR set IMSI on subscriber; IMSI=901700000004620 id=901700000004620
DVLR New subscr, IMSI: 901700000004620
DREF VLR subscr IMSI:901700000004620 usage increases to: 2
DREF VLR subscr IMSI:901700000004620 usage decreases to: 1
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node1()
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_auth()
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_post_ciph()
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: vlr_loc_upd_node_4()
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_IDLE}: state_chg to VLR_ULA_S_WAIT_HLR_UPD
DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Allocated
DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: Received Event UPD_HLR_VLR_E_START
DVLR GSUP tx: 04010809710000004026f0
GSUP --> HLR: OSMO_GSUP_MSGT_UPDATE_LOCATION_REQUEST: 04010809710000004026f0
DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_INIT}: state_chg to UPD_HLR_VLR_S_WAIT_FOR_DATA
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: Received Event SUBSCR_CONN_E_COMPLETE_LAYER_3
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_NEW}: state_chg to SUBSCR_CONN_S_AUTH_CIPH
DREF IMSI:901700000004620: MSC conn use - compl_l3 == 0 (0x0: )
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_UNUSED
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Awaiting results for Auth+Ciph, overruling event SUBSCR_CONN_E_UNUSED
lu_result_sent == 0
- HLR sends _INSERT_DATA_REQUEST, VLR responds with _INSERT_DATA_RESULT
<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: 10010809710000004026f00804036470f1
DVLR GSUP rx 17: 10010809710000004026f00804036470f1
DREF VLR subscr IMSI:901700000004620 usage increases to: 2
DVLR IMSI:901700000004620 has MSISDN:46071
DVLR SUBSCR(MSISDN:46071) VLR: update for IMSI=901700000004620 (MSISDN=46071, used=2)
DVLR GSUP tx: 12010809710000004026f0
GSUP --> HLR: OSMO_GSUP_MSGT_INSERT_DATA_RESULT: 12010809710000004026f0
DREF VLR subscr MSISDN:46071 usage decreases to: 1
<-- GSUP rx OSMO_GSUP_MSGT_INSERT_DATA_REQUEST: vlr_gsupc_read_cb() returns 0
lu_result_sent == 0
- HLR also sends GSUP _UPDATE_LOCATION_RESULT
<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: 06010809710000004026f0
DVLR GSUP rx 11: 06010809710000004026f0
DREF VLR subscr MSISDN:46071 usage increases to: 2
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_HLR_LU_RES
DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: Received Event UPD_HLR_VLR_E_UPD_LOC_ACK
DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_WAIT_FOR_DATA}: state_chg to UPD_HLR_VLR_S_DONE
DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Freeing instance
DVLR upd_hlr_vlr_fsm(LU:901700000004620){UPD_HLR_VLR_S_DONE}: Deallocated
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: Received Event VLR_ULA_E_UPD_HLR_COMPL
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_HLR_UPD}: state_chg to VLR_ULA_S_WAIT_LU_COMPL
DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Allocated
DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: is child of vlr_lu_fsm(LU:901700000004620)
DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: Received Event LU_COMPL_VLR_E_START
DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_INIT}: state_chg to LU_COMPL_VLR_S_WAIT_SUB_PRES
DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Allocated
DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: is child of lu_compl_vlr_fsm(LU:901700000004620)
DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: Received Event SUB_PRES_VLR_E_START
DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_INIT}: state_chg to SUB_PRES_VLR_S_DONE
DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Removing from parent lu_compl_vlr_fsm(LU:901700000004620)
DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Freeing instance
DVLR sub_pres_vlr_fsm(LU:901700000004620){SUB_PRES_VLR_S_DONE}: Deallocated
DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: Received Event LU_COMPL_VLR_E_SUB_PRES_COMPL
- sending LU Accept for MSISDN:46071
DREF VLR subscr MSISDN:46071 usage increases to: 3
DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_WAIT_SUB_PRES}: state_chg to LU_COMPL_VLR_S_DONE
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: Received Event VLR_ULA_E_LU_COMPL_SUCCESS
DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Removing from parent vlr_lu_fsm(LU:901700000004620)
DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Freeing instance
DVLR lu_compl_vlr_fsm(LU:901700000004620){LU_COMPL_VLR_S_DONE}: Deallocated
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_WAIT_LU_COMPL}: state_chg to VLR_ULA_S_DONE
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: Received Event SUBSCR_CONN_E_ACCEPTED
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_AUTH_CIPH}: state_chg to SUBSCR_CONN_S_ACCEPTED
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: Received Event SUBSCR_CONN_E_UNUSED
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_ACCEPTED}: state_chg to SUBSCR_CONN_S_RELEASING
DREF MSISDN:46071: MSC conn use + release == 1 (0x100: release)
DREF VLR subscr MSISDN:46071 usage increases to: 4
DREF VLR subscr MSISDN:46071 usage decreases to: 3
- BSSAP Clear --RAN_GERAN_A--> MS
DREF VLR subscr MSISDN:46071 usage decreases to: 2
<-- GSUP rx OSMO_GSUP_MSGT_UPDATE_LOCATION_RESULT: vlr_gsupc_read_cb() returns 0
- LU was successful, and the conn has already been closed
lu_result_sent == 1
bssap_clear_sent == 1
- BSS sends BSSMAP Clear Complete
DREF MSISDN:46071: MSC conn use - release == 0 (0x0: )
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: Received Event SUBSCR_CONN_E_UNUSED
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASING}: state_chg to SUBSCR_CONN_S_RELEASED
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Terminating (cause = OSMO_FSM_TERM_REGULAR)
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Terminating (cause = OSMO_FSM_TERM_PARENT)
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Removing from parent Subscr_Conn(LU:901700000004620)
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: fsm_lu_cleanup called with cause OSMO_FSM_TERM_PARENT
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Freeing instance
DVLR vlr_lu_fsm(LU:901700000004620){VLR_ULA_S_DONE}: Deallocated
DRLL MSISDN:46071: Freeing subscriber connection
DREF VLR subscr MSISDN:46071 usage decreases to: 1
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Freeing instance
DMM Subscr_Conn(LU:901700000004620){SUBSCR_CONN_S_RELEASED}: Deallocated
llist_count(&net->subscr_conns) == 0
DREF VLR subscr MSISDN:46071 usage increases to: 2
DREF VLR subscr MSISDN:46071 usage decreases to: 1
- Total time passed: 3901.000000 s
DVLR MSISDN:46071: Location Update expired
DREF VLR subscr MSISDN:46071 usage increases to: 2
DREF VLR subscr MSISDN:46071 usage decreases to: 1
DREF VLR subscr MSISDN:46071 usage decreases to: 0
DREF freeing VLR subscr MSISDN:46071
llist_count(&net->subscr_conns) == 0
===== test_no_authen_subscr_expire: SUCCESS
full talloc report on 'msgb' (total 0 bytes in 1 blocks)
talloc_total_blocks(tall_bsc_ctx) == 12
full talloc report on 'msgb' (total 0 bytes in 1 blocks)
talloc_total_blocks(tall_bsc_ctx) == 12

View File

@ -813,8 +813,15 @@ const struct timeval fake_time_start_time = { 123, 456 };
void fake_time_start()
{
struct timespec *clock_override;
osmo_gettimeofday_override_time = fake_time_start_time;
osmo_gettimeofday_override = true;
clock_override = osmo_clock_override_gettimespec(CLOCK_MONOTONIC);
OSMO_ASSERT(clock_override);
clock_override->tv_sec = fake_time_start_time.tv_sec;
clock_override->tv_nsec = fake_time_start_time.tv_usec * 1000;
osmo_clock_override_enable(CLOCK_MONOTONIC, true);
fake_time_passes(0, 0);
}

View File

@ -218,6 +218,7 @@ void fake_time_start();
{ \
struct timeval diff; \
osmo_gettimeofday_override_add(secs, usecs); \
osmo_clock_override_add(CLOCK_MONOTONIC, secs, usecs * 1000); \
timersub(&osmo_gettimeofday_override_time, &fake_time_start_time, &diff); \
btw("Total time passed: %d.%06d s", \
(int)diff.tv_sec, (int)diff.tv_usec); \