aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--openbsc/include/openbsc/gb_proxy.h2
-rw-r--r--openbsc/src/gprs/gb_proxy.c40
-rw-r--r--openbsc/src/gprs/gb_proxy_tlli.c12
-rw-r--r--openbsc/tests/gbproxy/gbproxy_test.ok14
4 files changed, 58 insertions, 10 deletions
diff --git a/openbsc/include/openbsc/gb_proxy.h b/openbsc/include/openbsc/gb_proxy.h
index 9b894632b..e9ca53184 100644
--- a/openbsc/include/openbsc/gb_proxy.h
+++ b/openbsc/include/openbsc/gb_proxy.h
@@ -150,6 +150,7 @@ struct gbproxy_tlli_info {
int imsi_acq_pending;
struct llist_head stored_msgs;
+ int imsi_acq_retries;
int enable_patching;
};
@@ -197,6 +198,7 @@ void gbproxy_update_tlli_state_after(
int gbproxy_remove_stale_tllis(struct gbproxy_peer *peer, time_t now);
void gbproxy_delete_tlli(struct gbproxy_peer *peer,
struct gbproxy_tlli_info *tlli_info);
+void gbproxy_tlli_info_discard_messages(struct gbproxy_tlli_info *tlli_info);
struct gbproxy_tlli_info *gbproxy_register_tlli(
struct gbproxy_peer *peer, uint32_t tlli,
diff --git a/openbsc/src/gprs/gb_proxy.c b/openbsc/src/gprs/gb_proxy.c
index 8b014eafc..fbac298e3 100644
--- a/openbsc/src/gprs/gb_proxy.c
+++ b/openbsc/src/gprs/gb_proxy.c
@@ -253,6 +253,22 @@ uint32_t gbproxy_make_sgsn_tlli(struct gbproxy_peer *peer,
return sgsn_tlli;
}
+/* Returns != 0 iff IMSI acquisition was in progress */
+int gbproxy_reset_imsi_acquisition(struct gbproxy_tlli_info* tlli_info)
+{
+ int in_progress = 0;
+ if (!tlli_info)
+ return 0;
+
+ if (tlli_info->imsi_acq_pending)
+ in_progress = 1;
+
+ gbproxy_tlli_info_discard_messages(tlli_info);
+ tlli_info->imsi_acq_pending = 0;
+
+ return in_progress;
+}
+
/* patch BSSGP message */
static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
struct msgb *msg,
@@ -315,10 +331,21 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
gbprox_update_current_raid(parse_ctx.bssgp_raid_enc, peer,
parse_ctx.llc_msg_name);
+ gprs_gb_log_parse_context(&parse_ctx, "BSSGP");
+
+ tlli_info = gbproxy_update_tlli_state_ul(peer, now, &parse_ctx);
+
if (parse_ctx.g48_hdr) {
switch (parse_ctx.g48_hdr->msg_type) {
case GSM48_MT_GMM_ATTACH_REQ:
rate_ctr_inc(&peer->ctrg->ctr[GBPROX_PEER_CTR_ATTACH_REQS]);
+ if (gbproxy_reset_imsi_acquisition(tlli_info)) {
+ LOGP(DLLC, LOGL_INFO,
+ "NSEI=%d(BSS) IMSI acquisition was in progress "
+ "when receiving an ATTACH_REQ.\n",
+ msgb_nsei(msg));
+ tlli_info->imsi_acq_retries += 1;
+ }
break;
default:
@@ -326,10 +353,6 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
}
}
- gprs_gb_log_parse_context(&parse_ctx, "BSSGP");
-
- tlli_info = gbproxy_update_tlli_state_ul(peer, now, &parse_ctx);
-
if (tlli_info && cfg->route_to_sgsn2 && gbproxy_check_tlli(peer, tlli_info)) {
sgsn_nsei = cfg->nsip_sgsn2_nsei;
send_msg_directly = 1;
@@ -415,8 +438,15 @@ static int gbprox_process_bssgp_ul(struct gbproxy_config *cfg,
/* Send IDENT REQ */
idreq_msg = gsm48_msgb_alloc();
gprs_put_identity_req(idreq_msg, GSM_MI_TYPE_IMSI);
+ /* Workaround to avoid N(U) collisions and to enable a restart
+ * of the IMSI acquisition procedure. This will work unless the
+ * SGSN has an initial V(UT) within [256-32, 256+n_retries]
+ * (see GSM 04.64, 8.4.2).
+ * TODO: Check whether it is sensible to rely on this, it might
+ * be an issue when P-TMSI patching is _not_ enabled and the SGSN
+ * doesn't reset V(UT) after a detach. */
gprs_push_llc_ui(idreq_msg, 0, GPRS_SAPI_GMM,
- /* TODO: use a real N(U) */0);
+ (tlli_info->imsi_acq_retries + 256) % 512);
gprs_push_bssgp_dl_unitdata(idreq_msg, tlli_info->tlli.current);
gbprox_relay2peer(idreq_msg, peer, msgb_bvci(msg));
msgb_free(idreq_msg);
diff --git a/openbsc/src/gprs/gb_proxy_tlli.c b/openbsc/src/gprs/gb_proxy_tlli.c
index 4ceaea92a..58a45aef5 100644
--- a/openbsc/src/gprs/gb_proxy_tlli.c
+++ b/openbsc/src/gprs/gb_proxy_tlli.c
@@ -98,11 +98,23 @@ struct gbproxy_tlli_info *gbproxy_find_tlli_by_mi(
return NULL;
}
+void gbproxy_tlli_info_discard_messages(struct gbproxy_tlli_info *tlli_info)
+{
+ struct msgb *msg, *nxt;
+
+ llist_for_each_entry_safe(msg, nxt, &tlli_info->stored_msgs, list) {
+ llist_del(&msg->list);
+ msgb_free(msg);
+ }
+}
+
void gbproxy_delete_tlli(struct gbproxy_peer *peer,
struct gbproxy_tlli_info *tlli_info)
{
struct gbproxy_patch_state *state = &peer->patch_state;
+ gbproxy_tlli_info_discard_messages(tlli_info);
+
llist_del(&tlli_info->list);
talloc_free(tlli_info);
state->enabled_tllis_count -= 1;
diff --git a/openbsc/tests/gbproxy/gbproxy_test.ok b/openbsc/tests/gbproxy/gbproxy_test.ok
index c307a72ee..1d7f4165b 100644
--- a/openbsc/tests/gbproxy/gbproxy_test.ok
+++ b/openbsc/tests/gbproxy/gbproxy_test.ok
@@ -2617,7 +2617,7 @@ CALLBACK, event 0, msg length 75, bvci 0x1002
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 28
-00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c0 01 08 15 01 ff 6c ba
+00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36
result (ATTACH REQUEST) = 0
@@ -3008,7 +3008,7 @@ CALLBACK, event 0, msg length 75, bvci 0x1002
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 28
-00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c0 01 08 15 01 ff 6c ba
+00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36
result (ATTACH REQUEST) = 0
@@ -3018,6 +3018,10 @@ PROCESSING ATTACH REQUEST from 0x01020304:1111
CALLBACK, event 0, msg length 75, bvci 0x1002
00 00 10 02 01 80 00 de ad 00 00 04 08 88 00 f1 99 00 63 60 12 34 00 80 0e 00 34 01 c0 19 08 01 02 f5 e0 21 08 02 05 f4 fb c5 46 79 11 22 33 40 50 60 19 18 b3 43 2b 25 96 62 00 60 80 9a c2 c6 62 00 60 80 ba c8 c6 62 00 60 80 00 b6 33 df
+NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg)
+MESSAGE to BSS at 0x01020304:1111, msg length 28
+00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 05 08 15 01 8f 47 9e
+
result (ATTACH REQUEST) = 0
Peers:
@@ -3030,7 +3034,7 @@ Peers:
Attach Request count : 3
TLLI cache size : 1
TLLI-Cache: 1
- TLLI 8000dead -> 7eb52dfb, IMSI (none), AGE 0, STORED 2, IMSI acquisition in progress
+ TLLI 8000dead -> 7eb52dfb, IMSI (none), AGE 0, STORED 1, IMSI acquisition in progress
Gbproxy global:
Invalid Routing Area Identifier : 1
BSSGP protocol error (SGSN): 1
@@ -3270,7 +3274,7 @@ CALLBACK, event 0, msg length 75, bvci 0x1002
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 28
-00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c0 01 08 15 01 ff 6c ba
+00 00 10 02 00 80 00 de ad 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36
result (ATTACH REQUEST) = 0
@@ -3573,7 +3577,7 @@ CALLBACK, event 0, msg length 75, bvci 0x1002
NS UNITDATA MESSAGE to BSS, BVCI 0x1002, msg length 24 (gprs_ns_sendmsg)
MESSAGE to BSS at 0x01020304:1111, msg length 28
-00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 00 09 41 c0 01 08 15 01 ff 6c ba
+00 00 10 02 00 80 00 be ef 00 50 20 16 82 02 58 0e 00 09 41 c4 01 08 15 01 b7 f8 36
result (ATTACH REQUEST) = 0