aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJacob Erlbeck <jerlbeck@sysmocom.de>2014-12-01 12:33:33 +0100
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-12-08 10:50:52 +0100
commitbd0cf1190a839bbaad38b86157eaa13b7c3f7ec4 (patch)
tree18a75a5c4687476ee4f64c113665108633a3a229
parent65d8273bf342944db12fecff9140bf4b9d3e6ad2 (diff)
sgsn: Change Auth&Ciph timer handling
Currently mmctx_timer_start is called from within gsm48_tx_gmm_auth_ciph_req which differs from the way e.g. the identification procedure is implemented. It also makes it more difficult to restart the procedure after timeout, which is not implemented yet. In addition, the timer is not properly stopped when an AUTH & CIPH response is received. This patch removes this timer start from gsm48_tx_gmm_auth_ciph_req, adds the retransmission of Auth & Ciph requests to the timer callback function, and properly stops the timer in gsm48_rx_gmm_auth_ciph_resp. Sponsored-by: On-Waves ehf
-rw-r--r--openbsc/include/openbsc/gprs_sgsn.h5
-rw-r--r--openbsc/src/gprs/gprs_gmm.c18
-rw-r--r--openbsc/src/gprs/gprs_sgsn.c1
3 files changed, 18 insertions, 6 deletions
diff --git a/openbsc/include/openbsc/gprs_sgsn.h b/openbsc/include/openbsc/gprs_sgsn.h
index 4572ac23d..1ffeb9fe7 100644
--- a/openbsc/include/openbsc/gprs_sgsn.h
+++ b/openbsc/include/openbsc/gprs_sgsn.h
@@ -10,6 +10,8 @@
#include <osmocom/crypt/gprs_cipher.h>
+#include <openbsc/gsm_data.h>
+
#define GSM_IMSI_LENGTH 17
#define GSM_IMEI_LENGTH 17
#define GSM_EXTENSION_LENGTH 15
@@ -84,7 +86,8 @@ struct sgsn_mm_ctx {
uint32_t sac_age;/* Iu: Service Area Code age */
/* VLR number */
uint32_t new_sgsn_addr;
- /* Authentication Triplets */
+ /* Authentication Triplet */
+ struct gsm_auth_tuple auth_triplet;
/* Kc */
/* Iu: CK, IK, KSI */
/* CKSN */
diff --git a/openbsc/src/gprs/gprs_gmm.c b/openbsc/src/gprs/gprs_gmm.c
index 8820396fe..6f54194b6 100644
--- a/openbsc/src/gprs/gprs_gmm.c
+++ b/openbsc/src/gprs/gprs_gmm.c
@@ -571,9 +571,6 @@ static int gsm48_tx_gmm_auth_ciph_req(struct sgsn_mm_ctx *mm, uint8_t *rand,
m_cksn[0] = (GSM48_IE_GMM_CIPH_CKSN << 4) | (key_seq & 0x07);
}
- /* Start T3360 */
- mmctx_timer_start(mm, 3360, GSM0408_T3360_SECS);
-
/* FIXME: make sure we don't send any other messages to the MS */
return gsm48_gmm_sendmsg(msg, 1, mm);
@@ -604,7 +601,8 @@ static int gsm48_rx_gmm_auth_ciph_resp(struct sgsn_mm_ctx *ctx,
struct gsm48_auth_ciph_resp *acr = (struct gsm48_auth_ciph_resp *)gh->data;
struct tlv_parsed tp;
- /* FIXME: Stop T3360 */
+ /* Stop T3360 */
+ mmctx_timer_stop(ctx, 3360);
tlv_parse(&tp, &gsm48_gmm_att_tlvdef, acr->data,
(msg->data + msg->len) - acr->data, 0, 0);
@@ -1332,6 +1330,7 @@ static int gsm0408_rcv_gmm(struct sgsn_mm_ctx *mmctx, struct msgb *msg,
static void mmctx_timer_cb(void *_mm)
{
struct sgsn_mm_ctx *mm = _mm;
+ struct gsm_auth_tuple *at;
mm->num_T_exp++;
@@ -1367,7 +1366,16 @@ static void mmctx_timer_cb(void *_mm)
mm_ctx_cleanup_free(mm, "T3360");
break;
}
- /* FIXME: re-transmit the respective msg and re-start timer */
+ /* Re-transmit the respective msg and re-start timer */
+ if (mm->auth_triplet.key_seq == GSM_KEY_SEQ_INVAL) {
+ LOGMMCTXP(LOGL_ERROR, mm,
+ "timeout: invalid auth triplet reference\n");
+ mm_ctx_cleanup_free(mm, "T3360");
+ break;
+ }
+ at = &mm->auth_triplet;
+
+ gsm48_tx_gmm_auth_ciph_req(mm, at->rand, at->key_seq, GPRS_ALGO_GEA0);
osmo_timer_schedule(&mm->timer, GSM0408_T3360_SECS, 0);
break;
case 3370: /* waiting for IDENTITY RESPONSE */
diff --git a/openbsc/src/gprs/gprs_sgsn.c b/openbsc/src/gprs/gprs_sgsn.c
index 62cdf0aaf..39bfa84bc 100644
--- a/openbsc/src/gprs/gprs_sgsn.c
+++ b/openbsc/src/gprs/gprs_sgsn.c
@@ -167,6 +167,7 @@ struct sgsn_mm_ctx *sgsn_mm_ctx_alloc(uint32_t tlli,
memcpy(&ctx->ra, raid, sizeof(ctx->ra));
ctx->tlli = tlli;
ctx->mm_state = GMM_DEREGISTERED;
+ ctx->auth_triplet.key_seq = GSM_KEY_SEQ_INVAL;
ctx->ctrg = rate_ctr_group_alloc(ctx, &mmctx_ctrg_desc, tlli);
INIT_LLIST_HEAD(&ctx->pdp_list);