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
This commit is contained in:
Jacob Erlbeck 2014-12-01 12:33:33 +01:00 committed by Holger Hans Peter Freyther
parent 65d8273bf3
commit bd0cf1190a
3 changed files with 18 additions and 6 deletions

View File

@ -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 */

View File

@ -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 */

View File

@ -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);