gbproxy: Pass tlli_info around
This patch modifies the code to pass a pointer to the tlli_info around once it has been acquired. To achieve this, gbprox_register_tlli() and gbprox_update_state() are modified to return it (if it has been found or created), and gbprox_patch_llc(), gbprox_patch_bssgp(), and gbprox_update_state_after() are modified to take it as parameter. Add a new function gbprox_touch_tlli() to update timestamp and list ordering for existing tlli_infos. The motivation behind this patch is to make the tlli_info available to the patching code and to avoid repeated searches for the same TLLI. Sponsored-by: On-Waves ehf
This commit is contained in:
parent
cefe85c2b7
commit
ccc5970ebb
|
@ -124,9 +124,11 @@ int gbprox_cleanup_peers(struct gbproxy_config *cfg, uint16_t nsei, uint16_t bvc
|
|||
struct gbproxy_peer *gbprox_peer_by_nsei(struct gbproxy_config *cfg, uint16_t nsei);
|
||||
|
||||
struct gbproxy_tlli_info *gbprox_find_tlli_by_mi(struct gbproxy_peer *peer,
|
||||
const uint8_t *mi_data, size_t mi_data_len);
|
||||
void gbprox_register_tlli(struct gbproxy_peer *peer, uint32_t tlli,
|
||||
const uint8_t *imsi, size_t imsi_len, time_t now);
|
||||
const uint8_t *mi_data,
|
||||
size_t mi_data_len);
|
||||
struct gbproxy_tlli_info *gbprox_register_tlli(
|
||||
struct gbproxy_peer *peer, uint32_t tlli,
|
||||
const uint8_t *imsi, size_t imsi_len, time_t now);
|
||||
struct gbproxy_peer *gbproxy_peer_alloc(struct gbproxy_config *cfg, uint16_t bvci);
|
||||
void gbproxy_peer_free(struct gbproxy_peer *peer);
|
||||
|
||||
|
|
|
@ -658,8 +658,16 @@ void gbprox_reassign_tlli(struct gbproxy_tlli_info *tlli_info,
|
|||
tlli_info->tlli = new_tlli;
|
||||
}
|
||||
|
||||
void gbprox_register_tlli(struct gbproxy_peer *peer, uint32_t tlli,
|
||||
const uint8_t *imsi, size_t imsi_len, time_t now)
|
||||
void gbprox_touch_tlli(struct gbproxy_peer *peer,
|
||||
struct gbproxy_tlli_info *tlli_info, time_t now)
|
||||
{
|
||||
gbprox_get_detached_tlli_info(peer, tlli_info, tlli_info->tlli);
|
||||
gbprox_attach_tlli_info(peer, now, tlli_info);
|
||||
}
|
||||
|
||||
struct gbproxy_tlli_info *gbprox_register_tlli(
|
||||
struct gbproxy_peer *peer, uint32_t tlli,
|
||||
const uint8_t *imsi, size_t imsi_len, time_t now)
|
||||
{
|
||||
struct gbproxy_tlli_info *tlli_info;
|
||||
int enable_patching = -1;
|
||||
|
@ -669,7 +677,7 @@ void gbprox_register_tlli(struct gbproxy_peer *peer, uint32_t tlli,
|
|||
if (is_mi_imsi(imsi, imsi_len)) {
|
||||
enable_patching = gbprox_check_imsi(peer, imsi, imsi_len);
|
||||
if (enable_patching < 0)
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tlli_info = gbprox_find_tlli(peer, tlli);
|
||||
|
@ -696,8 +704,11 @@ void gbprox_register_tlli(struct gbproxy_peer *peer, uint32_t tlli,
|
|||
|
||||
gbprox_attach_tlli_info(peer, now, tlli_info);
|
||||
gbprox_update_tlli_info(tlli_info, imsi, imsi_len);
|
||||
|
||||
if (enable_patching >= 0)
|
||||
tlli_info->enable_patching = enable_patching;
|
||||
|
||||
return tlli_info;
|
||||
}
|
||||
|
||||
static void gbprox_unregister_tlli(struct gbproxy_peer *peer, uint32_t tlli)
|
||||
|
@ -1213,11 +1224,13 @@ static int gbprox_parse_llc(uint8_t *llc, size_t llc_len,
|
|||
}
|
||||
|
||||
static int gbprox_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
|
||||
struct gbproxy_peer *peer, int *len_change,
|
||||
struct gbproxy_peer *peer,
|
||||
struct gbproxy_tlli_info *tlli_info, int *len_change,
|
||||
struct gbproxy_parse_context *parse_ctx) __attribute__((nonnull));
|
||||
|
||||
static int gbprox_patch_llc(struct msgb *msg, uint8_t *llc, size_t llc_len,
|
||||
struct gbproxy_peer *peer, int *len_change,
|
||||
struct gbproxy_peer *peer,
|
||||
struct gbproxy_tlli_info *tlli_info, int *len_change,
|
||||
struct gbproxy_parse_context *parse_ctx)
|
||||
{
|
||||
struct gprs_llc_hdr_parsed *ghp = &parse_ctx->llc_hdr_parsed;
|
||||
|
@ -1316,13 +1329,14 @@ static void gbprox_log_parse_context(struct gbproxy_parse_context *parse_ctx,
|
|||
LOGP(DGPRS, LOGL_DEBUG, "\n");
|
||||
}
|
||||
|
||||
static void gbprox_update_state(struct gbproxy_peer *peer, time_t now,
|
||||
struct gbproxy_parse_context *parse_ctx)
|
||||
static struct gbproxy_tlli_info *gbprox_update_state(
|
||||
struct gbproxy_peer *peer, time_t now,
|
||||
struct gbproxy_parse_context *parse_ctx)
|
||||
{
|
||||
struct gbproxy_tlli_info *tlli_info = NULL;
|
||||
|
||||
if (!peer->cfg->check_imsi)
|
||||
return;
|
||||
return NULL;
|
||||
|
||||
if (parse_ctx->tlli_enc)
|
||||
tlli_info = gbprox_find_tlli(peer, parse_ctx->tlli);
|
||||
|
@ -1355,25 +1369,40 @@ static void gbprox_update_state(struct gbproxy_peer *peer, time_t now,
|
|||
LOGP(DGPRS, LOGL_ERROR,
|
||||
"Failed to parse new TLLI/PTMSI (current is %08x)\n",
|
||||
parse_ctx->tlli);
|
||||
return;
|
||||
return tlli_info;
|
||||
}
|
||||
new_tlli = gprs_tmsi2tlli(new_ptmsi, TLLI_LOCAL);
|
||||
LOGP(DGPRS, LOGL_INFO,
|
||||
"Got new TLLI/PTMSI %08x/%08x (current is %08x)\n",
|
||||
new_tlli, new_ptmsi, parse_ctx->tlli);
|
||||
if (tlli_info)
|
||||
if (tlli_info) {
|
||||
gbprox_reassign_tlli(tlli_info, peer, new_tlli);
|
||||
gbprox_register_tlli(peer, new_tlli,
|
||||
parse_ctx->imsi, parse_ctx->imsi_len, now);
|
||||
gbprox_touch_tlli(peer, tlli_info, now);
|
||||
} else {
|
||||
tlli_info =
|
||||
gbprox_register_tlli(peer, new_tlli,
|
||||
parse_ctx->imsi,
|
||||
parse_ctx->imsi_len, now);
|
||||
}
|
||||
} else if (parse_ctx->tlli_enc && parse_ctx->llc) {
|
||||
gbprox_register_tlli(peer, parse_ctx->tlli,
|
||||
parse_ctx->imsi, parse_ctx->imsi_len, now);
|
||||
tlli_info =
|
||||
gbprox_register_tlli(peer, parse_ctx->tlli,
|
||||
parse_ctx->imsi,
|
||||
parse_ctx->imsi_len, now);
|
||||
} else if (tlli_info) {
|
||||
gbprox_touch_tlli(peer, tlli_info, now);
|
||||
}
|
||||
|
||||
return;
|
||||
if (parse_ctx->imsi && tlli_info && tlli_info->mi_data_len == 0)
|
||||
gbprox_update_tlli_info(tlli_info,
|
||||
parse_ctx->imsi, parse_ctx->imsi_len);
|
||||
|
||||
return tlli_info;
|
||||
}
|
||||
|
||||
static void gbprox_update_state_after(struct gbproxy_peer *peer, time_t now,
|
||||
static void gbprox_update_state_after(struct gbproxy_peer *peer,
|
||||
struct gbproxy_tlli_info *tlli_info,
|
||||
time_t now,
|
||||
struct gbproxy_parse_context *parse_ctx)
|
||||
{
|
||||
if (parse_ctx->invalidate_tlli)
|
||||
|
@ -1464,11 +1493,13 @@ static int gbprox_parse_bssgp(uint8_t *bssgp, size_t bssgp_len,
|
|||
|
||||
/* patch BSSGP message to use core_mcc/mnc on the SGSN side */
|
||||
static void gbprox_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
|
||||
struct gbproxy_peer *peer, int *len_change,
|
||||
struct gbproxy_peer *peer,
|
||||
struct gbproxy_tlli_info *tlli_info, int *len_change,
|
||||
struct gbproxy_parse_context *parse_ctx)
|
||||
__attribute__((nonnull));
|
||||
static void gbprox_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_len,
|
||||
struct gbproxy_peer *peer, int *len_change,
|
||||
struct gbproxy_peer *peer,
|
||||
struct gbproxy_tlli_info *tlli_info, int *len_change,
|
||||
struct gbproxy_parse_context *parse_ctx)
|
||||
{
|
||||
const char *err_info = NULL;
|
||||
|
@ -1500,8 +1531,8 @@ static void gbprox_patch_bssgp(struct msgb *msg, uint8_t *bssgp, size_t bssgp_le
|
|||
size_t llc_len = parse_ctx->llc_len;
|
||||
int llc_len_change = 0;
|
||||
|
||||
gbprox_patch_llc(msg, llc, llc_len, peer, &llc_len_change,
|
||||
parse_ctx);
|
||||
gbprox_patch_llc(msg, llc, llc_len, peer, tlli_info,
|
||||
&llc_len_change, parse_ctx);
|
||||
/* Note that the APN might have been resized here, but no
|
||||
* pointer int the parse_ctx will refer to an adress after the
|
||||
* APN. So it's possible to patch first and do the TLLI
|
||||
|
@ -1549,6 +1580,7 @@ static void gbprox_process_bssgp_message(struct gbproxy_config *cfg,
|
|||
int rc;
|
||||
int len_change = 0;
|
||||
time_t now;
|
||||
struct gbproxy_tlli_info *tlli_info;
|
||||
|
||||
if (!cfg->core_mcc && !cfg->core_mnc && !cfg->core_apn)
|
||||
return;
|
||||
|
@ -1587,12 +1619,12 @@ static void gbprox_process_bssgp_message(struct gbproxy_config *cfg,
|
|||
|
||||
now = time(NULL);
|
||||
|
||||
gbprox_update_state(peer, now, &parse_ctx);
|
||||
tlli_info = gbprox_update_state(peer, now, &parse_ctx);
|
||||
|
||||
gbprox_patch_bssgp(msg, msgb_bssgph(msg), msgb_bssgp_len(msg),
|
||||
peer, &len_change, &parse_ctx);
|
||||
peer, tlli_info, &len_change, &parse_ctx);
|
||||
|
||||
gbprox_update_state_after(peer, now, &parse_ctx);
|
||||
gbprox_update_state_after(peer, tlli_info, now, &parse_ctx);
|
||||
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1358,12 +1358,18 @@ static void test_gbproxy_tlli_expire(void)
|
|||
OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
|
||||
|
||||
printf(" Add TLLI 1, IMSI 1\n");
|
||||
gbprox_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
|
||||
tlli_info = gbprox_register_tlli(peer, tlli1,
|
||||
imsi1, ARRAY_SIZE(imsi1), now);
|
||||
OSMO_ASSERT(tlli_info);
|
||||
OSMO_ASSERT(tlli_info->tlli == tlli1);
|
||||
OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
|
||||
|
||||
/* replace the old entry */
|
||||
printf(" Add TLLI 2, IMSI 1 (should replace TLLI 1)\n");
|
||||
gbprox_register_tlli(peer, tlli2, imsi1, ARRAY_SIZE(imsi1), now);
|
||||
tlli_info = gbprox_register_tlli(peer, tlli2,
|
||||
imsi1, ARRAY_SIZE(imsi1), now);
|
||||
OSMO_ASSERT(tlli_info);
|
||||
OSMO_ASSERT(tlli_info->tlli == tlli2);
|
||||
OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
|
||||
|
||||
dump_peers(stdout, 2, now, &cfg);
|
||||
|
@ -1391,12 +1397,18 @@ static void test_gbproxy_tlli_expire(void)
|
|||
OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 0);
|
||||
|
||||
printf(" Add TLLI 1, IMSI 1\n");
|
||||
gbprox_register_tlli(peer, tlli1, imsi1, ARRAY_SIZE(imsi1), now);
|
||||
tlli_info = gbprox_register_tlli(peer, tlli1,
|
||||
imsi1, ARRAY_SIZE(imsi1), now);
|
||||
OSMO_ASSERT(tlli_info);
|
||||
OSMO_ASSERT(tlli_info->tlli == tlli1);
|
||||
OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
|
||||
|
||||
/* try to replace the old entry */
|
||||
printf(" Add TLLI 1, IMSI 2 (should replace IMSI 1)\n");
|
||||
gbprox_register_tlli(peer, tlli1, imsi2, ARRAY_SIZE(imsi2), now);
|
||||
tlli_info = gbprox_register_tlli(peer, tlli1,
|
||||
imsi2, ARRAY_SIZE(imsi2), now);
|
||||
OSMO_ASSERT(tlli_info);
|
||||
OSMO_ASSERT(tlli_info->tlli == tlli1);
|
||||
OSMO_ASSERT(peer->patch_state.enabled_tllis_count == 1);
|
||||
|
||||
dump_peers(stdout, 2, now, &cfg);
|
||||
|
|
Loading…
Reference in New Issue