blob: 4c97f8abe24eeecaf033014607e00dca4a307a06 [file] [log] [blame]
Jacob Erlbeck9114bee2014-08-19 12:21:01 +02001/* Gb-proxy TLLI state handling */
2
3/* (C) 2014 by On-Waves
4 * All Rights Reserved
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 *
19 */
20
Harald Welte6e688082014-08-24 17:38:18 +020021#include <osmocom/gsm/gsm48.h>
22
Jacob Erlbeck9114bee2014-08-19 12:21:01 +020023#include <openbsc/gb_proxy.h>
24
25#include <openbsc/gprs_utils.h>
26#include <openbsc/gprs_gb_parse.h>
27
Jacob Erlbeck9114bee2014-08-19 12:21:01 +020028#include <openbsc/debug.h>
29
30#include <osmocom/gsm/gsm_utils.h>
31
32#include <osmocom/core/rate_ctr.h>
33#include <osmocom/core/talloc.h>
34
35struct gbproxy_tlli_info *gbproxy_find_tlli(struct gbproxy_peer *peer,
36 uint32_t tlli)
37{
38 struct gbproxy_tlli_info *tlli_info;
39 struct gbproxy_patch_state *state = &peer->patch_state;
40
41 llist_for_each_entry(tlli_info, &state->enabled_tllis, list)
42 if (tlli_info->tlli.current == tlli ||
43 tlli_info->tlli.assigned == tlli)
44 return tlli_info;
45
46 return NULL;
47}
48
49struct gbproxy_tlli_info *gbproxy_find_tlli_by_ptmsi(
50 struct gbproxy_peer *peer,
51 uint32_t ptmsi)
52{
53 struct gbproxy_tlli_info *tlli_info;
54 struct gbproxy_patch_state *state = &peer->patch_state;
55
56 llist_for_each_entry(tlli_info, &state->enabled_tllis, list)
57 if (tlli_info->tlli.ptmsi == ptmsi)
58 return tlli_info;
59
60 return NULL;
61}
62
63struct gbproxy_tlli_info *gbproxy_find_tlli_by_sgsn_tlli(
64 struct gbproxy_peer *peer,
65 uint32_t tlli)
66{
67 struct gbproxy_tlli_info *tlli_info;
68 struct gbproxy_patch_state *state = &peer->patch_state;
69
70 llist_for_each_entry(tlli_info, &state->enabled_tllis, list)
71 if (tlli_info->sgsn_tlli.current == tlli ||
72 tlli_info->sgsn_tlli.assigned == tlli)
73 return tlli_info;
74
75 return NULL;
76}
77
78struct gbproxy_tlli_info *gbproxy_find_tlli_by_mi(
79 struct gbproxy_peer *peer,
80 const uint8_t *mi_data,
81 size_t mi_data_len)
82{
83 struct gbproxy_tlli_info *tlli_info;
84 struct gbproxy_patch_state *state = &peer->patch_state;
85
86 if (!gprs_is_mi_imsi(mi_data, mi_data_len))
87 return NULL;
88
89 llist_for_each_entry(tlli_info, &state->enabled_tllis, list) {
90 if (tlli_info->mi_data_len != mi_data_len)
91 continue;
92 if (memcmp(tlli_info->mi_data, mi_data, mi_data_len) != 0)
93 continue;
94
95 return tlli_info;
96 }
97
98 return NULL;
99}
100
101void gbproxy_delete_tlli(struct gbproxy_peer *peer,
102 struct gbproxy_tlli_info *tlli_info)
103{
104 struct gbproxy_patch_state *state = &peer->patch_state;
105
106 llist_del(&tlli_info->list);
107 talloc_free(tlli_info);
108 state->enabled_tllis_count -= 1;
109
110 peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
111 state->enabled_tllis_count;
112}
113
114void gbproxy_delete_tllis(struct gbproxy_peer *peer)
115{
116 struct gbproxy_tlli_info *tlli_info, *nxt;
117 struct gbproxy_patch_state *state = &peer->patch_state;
118
119 llist_for_each_entry_safe(tlli_info, nxt, &state->enabled_tllis, list)
120 gbproxy_delete_tlli(peer, tlli_info);
121
122 OSMO_ASSERT(state->enabled_tllis_count == 0);
123 OSMO_ASSERT(llist_empty(&state->enabled_tllis));
124}
125
126static void gbproxy_attach_tlli_info(struct gbproxy_peer *peer, time_t now,
127 struct gbproxy_tlli_info *tlli_info)
128{
129 struct gbproxy_patch_state *state = &peer->patch_state;
130
131 tlli_info->timestamp = now;
132 llist_add(&tlli_info->list, &state->enabled_tllis);
133 state->enabled_tllis_count += 1;
134
135 peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
136 state->enabled_tllis_count;
137}
138
139int gbproxy_remove_stale_tllis(struct gbproxy_peer *peer, time_t now)
140{
141 struct gbproxy_patch_state *state = &peer->patch_state;
142 int exceeded_max_len = 0;
143 int deleted_count = 0;
144 int check_for_age;
145
146 if (peer->cfg->tlli_max_len > 0)
147 exceeded_max_len =
148 state->enabled_tllis_count - peer->cfg->tlli_max_len;
149
150 check_for_age = peer->cfg->tlli_max_age > 0;
151
152 for (; exceeded_max_len > 0; exceeded_max_len--) {
153 struct gbproxy_tlli_info *tlli_info;
154 OSMO_ASSERT(!llist_empty(&state->enabled_tllis));
155 tlli_info = llist_entry(state->enabled_tllis.prev,
156 struct gbproxy_tlli_info,
157 list);
158 LOGP(DGPRS, LOGL_INFO,
159 "Removing TLLI %08x from list "
160 "(stale, length %d, max_len exceeded)\n",
161 tlli_info->tlli.current, state->enabled_tllis_count);
162
163 gbproxy_delete_tlli(peer, tlli_info);
164 deleted_count += 1;
165 }
166
167 while (check_for_age && !llist_empty(&state->enabled_tllis)) {
168 time_t age;
169 struct gbproxy_tlli_info *tlli_info;
170 tlli_info = llist_entry(state->enabled_tllis.prev,
171 struct gbproxy_tlli_info,
172 list);
173 age = now - tlli_info->timestamp;
174 /* age < 0 only happens after system time jumps, discard entry */
175 if (age <= peer->cfg->tlli_max_age && age >= 0) {
176 check_for_age = 0;
177 continue;
178 }
179
180 LOGP(DGPRS, LOGL_INFO,
181 "Removing TLLI %08x from list "
182 "(stale, age %d, max_age exceeded)\n",
183 tlli_info->tlli.current, (int)age);
184
185 gbproxy_delete_tlli(peer, tlli_info);
186 deleted_count += 1;
187 }
188
189 return deleted_count;
190}
191
192static struct gbproxy_tlli_info *gbproxy_tlli_info_alloc(
193 struct gbproxy_peer *peer)
194{
195 struct gbproxy_tlli_info *tlli_info;
196
197 tlli_info = talloc_zero(peer, struct gbproxy_tlli_info);
198 tlli_info->tlli.ptmsi = GSM_RESERVED_TMSI;
199 tlli_info->sgsn_tlli.ptmsi = GSM_RESERVED_TMSI;
200
Jacob Erlbeck5f4ef322014-08-22 17:10:01 +0200201 INIT_LLIST_HEAD(&tlli_info->stored_msgs);
202
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200203 return tlli_info;
204}
205
206static void gbproxy_detach_tlli_info(
207 struct gbproxy_peer *peer,
208 struct gbproxy_tlli_info *tlli_info)
209{
210 struct gbproxy_patch_state *state = &peer->patch_state;
211
212 llist_del(&tlli_info->list);
213 OSMO_ASSERT(state->enabled_tllis_count > 0);
214 state->enabled_tllis_count -= 1;
215
216 peer->ctrg->ctr[GBPROX_PEER_CTR_TLLI_CACHE_SIZE].current =
217 state->enabled_tllis_count;
218}
219
220static void gbproxy_update_tlli_info(struct gbproxy_tlli_info *tlli_info,
221 const uint8_t *imsi, size_t imsi_len)
222{
223 if (!gprs_is_mi_imsi(imsi, imsi_len))
224 return;
225
226 tlli_info->mi_data_len = imsi_len;
227 tlli_info->mi_data =
228 talloc_realloc_size(tlli_info, tlli_info->mi_data, imsi_len);
229 OSMO_ASSERT(tlli_info->mi_data != NULL);
230 memcpy(tlli_info->mi_data, imsi, imsi_len);
231}
232
233void gbproxy_reassign_tlli(struct gbproxy_tlli_state *tlli_state,
234 struct gbproxy_peer *peer, uint32_t new_tlli)
235{
236 if (new_tlli == tlli_state->current)
237 return;
238
239 LOGP(DGPRS, LOGL_INFO,
240 "The TLLI has been reassigned from %08x to %08x\n",
241 tlli_state->current, new_tlli);
242
243 /* Remember assigned TLLI */
244 tlli_state->assigned = new_tlli;
245 tlli_state->bss_validated = 0;
246 tlli_state->net_validated = 0;
247}
248
249uint32_t gbproxy_map_tlli(uint32_t other_tlli,
250 struct gbproxy_tlli_info *tlli_info, int to_bss)
251{
252 uint32_t tlli = 0;
253 struct gbproxy_tlli_state *src, *dst;
254 if (to_bss) {
255 src = &tlli_info->sgsn_tlli;
256 dst = &tlli_info->tlli;
257 } else {
258 src = &tlli_info->tlli;
259 dst = &tlli_info->sgsn_tlli;
260 }
261 if (src->current == other_tlli)
262 tlli = dst->current;
263 else if (src->assigned == other_tlli)
264 tlli = dst->assigned;
265
266 return tlli;
267}
268
269static void gbproxy_validate_tlli(struct gbproxy_tlli_state *tlli_state,
270 uint32_t tlli, int to_bss)
271{
272 LOGP(DGPRS, LOGL_DEBUG,
273 "%s({current = %08x, assigned = %08x, net_vld = %d, bss_vld = %d}, %08x)\n",
274 __func__, tlli_state->current, tlli_state->assigned,
275 tlli_state->net_validated, tlli_state->bss_validated, tlli);
276
277 if (!tlli_state->assigned || tlli_state->assigned != tlli)
278 return;
279
280 /* TODO: Is this ok? Check spec */
281 if (gprs_tlli_type(tlli) != TLLI_LOCAL)
282 return;
283
284 /* See GSM 04.08, 4.7.1.5 */
285 if (to_bss)
286 tlli_state->net_validated = 1;
287 else
288 tlli_state->bss_validated = 1;
289
290 if (!tlli_state->bss_validated || !tlli_state->net_validated)
291 return;
292
293 LOGP(DGPRS, LOGL_INFO,
294 "The TLLI %08x has been validated (was %08x)\n",
295 tlli_state->assigned, tlli_state->current);
296
297 tlli_state->current = tlli;
298 tlli_state->assigned = 0;
299}
300
301void gbproxy_touch_tlli(struct gbproxy_peer *peer,
302 struct gbproxy_tlli_info *tlli_info, time_t now)
303{
304 gbproxy_detach_tlli_info(peer, tlli_info);
305 gbproxy_attach_tlli_info(peer, now, tlli_info);
306}
307
308struct gbproxy_tlli_info *gbproxy_register_tlli(
309 struct gbproxy_peer *peer, uint32_t tlli,
310 const uint8_t *imsi, size_t imsi_len, time_t now)
311{
312 struct gbproxy_tlli_info *tlli_info;
313 int enable_patching = -1;
Jacob Erlbeckecbd56c2014-08-26 10:01:57 +0200314 int tlli_already_known = 0;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200315
316 /* Check, whether the IMSI matches */
317 if (gprs_is_mi_imsi(imsi, imsi_len)) {
318 enable_patching = gbproxy_check_imsi(peer, imsi, imsi_len);
319 if (enable_patching < 0)
320 return NULL;
321 }
322
323 tlli_info = gbproxy_find_tlli(peer, tlli);
324
325 if (!tlli_info) {
326 tlli_info = gbproxy_find_tlli_by_mi(peer, imsi, imsi_len);
327
328 if (tlli_info) {
329 /* TLLI has changed somehow, adjust it */
330 LOGP(DGPRS, LOGL_INFO,
331 "The TLLI has changed from %08x to %08x\n",
332 tlli_info->tlli.current, tlli);
333 tlli_info->tlli.current = tlli;
334 }
335 }
336
337 if (!tlli_info) {
338 tlli_info = gbproxy_tlli_info_alloc(peer);
339 tlli_info->tlli.current = tlli;
340 } else {
341 gbproxy_detach_tlli_info(peer, tlli_info);
342 tlli_already_known = 1;
343 }
344
345 OSMO_ASSERT(tlli_info != NULL);
346
347 if (!tlli_already_known)
348 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list\n", tlli);
349
350 gbproxy_attach_tlli_info(peer, now, tlli_info);
351 gbproxy_update_tlli_info(tlli_info, imsi, imsi_len);
352
353 if (enable_patching >= 0)
354 tlli_info->enable_patching = enable_patching;
355
356 return tlli_info;
357}
358
359static void gbproxy_unregister_tlli(struct gbproxy_peer *peer, uint32_t tlli)
360{
361 struct gbproxy_tlli_info *tlli_info;
362
363 tlli_info = gbproxy_find_tlli(peer, tlli);
364 if (tlli_info) {
365 LOGP(DGPRS, LOGL_INFO,
366 "Removing TLLI %08x from list\n",
367 tlli);
368 gbproxy_delete_tlli(peer, tlli_info);
369 }
370}
371
Jacob Erlbeck18a37872014-09-08 09:59:16 +0200372int gbproxy_check_tlli(struct gbproxy_peer *peer,
373 struct gbproxy_tlli_info *tlli_info)
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200374{
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200375 if (!peer->cfg->check_imsi)
376 return 1;
377
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200378 return tlli_info != NULL && tlli_info->enable_patching;
379}
380
381struct gbproxy_tlli_info *gbproxy_update_tlli_state_ul(
382 struct gbproxy_peer *peer,
383 time_t now,
384 struct gprs_gb_parse_context *parse_ctx)
385{
386 struct gbproxy_tlli_info *tlli_info = NULL;
387
388 if (parse_ctx->tlli_enc)
389 tlli_info = gbproxy_find_tlli(peer, parse_ctx->tlli);
390
391 if (parse_ctx->tlli_enc && parse_ctx->llc) {
392 uint32_t sgsn_tlli;
393 if (!tlli_info) {
394 tlli_info =
395 gbproxy_register_tlli(peer, parse_ctx->tlli,
396 parse_ctx->imsi,
397 parse_ctx->imsi_len, now);
398 /* Setup TLLIs */
399 sgsn_tlli = gbproxy_make_sgsn_tlli(peer, tlli_info,
400 parse_ctx->tlli);
401 tlli_info->sgsn_tlli.current = sgsn_tlli;
402 } else {
403 sgsn_tlli = gbproxy_map_tlli(parse_ctx->tlli, tlli_info, 0);
404 if (!sgsn_tlli)
405 sgsn_tlli = gbproxy_make_sgsn_tlli(peer, tlli_info,
406 parse_ctx->tlli);
407
408 gbproxy_validate_tlli(&tlli_info->tlli,
409 parse_ctx->tlli, 0);
410 gbproxy_validate_tlli(&tlli_info->sgsn_tlli,
411 sgsn_tlli, 0);
412 gbproxy_touch_tlli(peer, tlli_info, now);
413 }
414 } else if (tlli_info) {
415 gbproxy_touch_tlli(peer, tlli_info, now);
416 }
417
418 if (parse_ctx->imsi && tlli_info && tlli_info->mi_data_len == 0) {
419 int enable_patching;
420 gbproxy_update_tlli_info(tlli_info,
421 parse_ctx->imsi, parse_ctx->imsi_len);
422
423 /* Check, whether the IMSI matches */
424 enable_patching = gbproxy_check_imsi(peer, parse_ctx->imsi,
425 parse_ctx->imsi_len);
426 if (enable_patching >= 0)
427 tlli_info->enable_patching = enable_patching;
428 }
429
430 return tlli_info;
431}
432
433struct gbproxy_tlli_info *gbproxy_update_tlli_state_dl(
434 struct gbproxy_peer *peer,
435 time_t now,
436 struct gprs_gb_parse_context *parse_ctx)
437{
438 struct gbproxy_tlli_info *tlli_info = NULL;
439
440 if (parse_ctx->tlli_enc)
441 tlli_info = gbproxy_find_tlli_by_sgsn_tlli(peer, parse_ctx->tlli);
442
Jacob Erlbeck37fda772014-09-05 10:22:27 +0200443 if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc && tlli_info) {
444 /* A new P-TMSI has been signalled in the message,
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200445 * register new TLLI */
446 uint32_t new_sgsn_ptmsi;
447 uint32_t new_sgsn_tlli;
448 uint32_t new_bss_ptmsi;
449 uint32_t new_bss_tlli = 0;
450 if (!gprs_parse_mi_tmsi(parse_ctx->new_ptmsi_enc, GSM48_TMSI_LEN,
451 &new_sgsn_ptmsi)) {
452 LOGP(DGPRS, LOGL_ERROR,
453 "Failed to parse new TLLI/PTMSI (current is %08x)\n",
454 parse_ctx->tlli);
455 return tlli_info;
456 }
457 new_sgsn_tlli = gprs_tmsi2tlli(new_sgsn_ptmsi, TLLI_LOCAL);
458 new_bss_ptmsi = gbproxy_make_bss_ptmsi(peer, new_sgsn_ptmsi);
459 if (new_bss_ptmsi != GSM_RESERVED_TMSI)
460 new_bss_tlli = gprs_tmsi2tlli(new_bss_ptmsi, TLLI_LOCAL);
461 LOGP(DGPRS, LOGL_INFO,
462 "Got new TLLI(PTMSI) %08x(%08x) from SGSN, using %08x(%08x)\n",
463 new_sgsn_tlli, new_sgsn_ptmsi, new_bss_tlli, new_bss_ptmsi);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200464
Jacob Erlbeck37fda772014-09-05 10:22:27 +0200465 gbproxy_reassign_tlli(&tlli_info->sgsn_tlli,
466 peer, new_sgsn_tlli);
467 gbproxy_reassign_tlli(&tlli_info->tlli,
468 peer, new_bss_tlli);
469 gbproxy_touch_tlli(peer, tlli_info, now);
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200470 /* Setup PTMSIs */
471 tlli_info->sgsn_tlli.ptmsi = new_sgsn_ptmsi;
472 tlli_info->tlli.ptmsi = new_bss_ptmsi;
Jacob Erlbeck37fda772014-09-05 10:22:27 +0200473 } else if (parse_ctx->tlli_enc && parse_ctx->new_ptmsi_enc && !tlli_info &&
474 !peer->cfg->patch_ptmsi) {
475 /* A new P-TMSI has been signalled in the message with an unknown
476 * TLLI, create a new tlli_info */
477 uint32_t new_ptmsi;
478 if (!gprs_parse_mi_tmsi(parse_ctx->new_ptmsi_enc, GSM48_TMSI_LEN,
479 &new_ptmsi)) {
480 LOGP(DGPRS, LOGL_ERROR,
481 "Failed to parse new PTMSI (TLLI is %08x)\n",
482 parse_ctx->tlli);
483 return tlli_info;
484 }
485
486 LOGP(DGPRS, LOGL_INFO,
487 "Adding TLLI %08x to list (SGSN, new P-TMSI is %08x)\n",
488 parse_ctx->tlli, new_ptmsi);
489
490 tlli_info = gbproxy_tlli_info_alloc(peer);
491 tlli_info->sgsn_tlli.current = parse_ctx->tlli;;
492 tlli_info->tlli.current = parse_ctx->tlli;;
493 tlli_info->sgsn_tlli.ptmsi = new_ptmsi;
494 tlli_info->tlli.ptmsi = new_ptmsi;
495 } else if (parse_ctx->tlli_enc && parse_ctx->llc && !tlli_info &&
496 !peer->cfg->patch_ptmsi) {
497 /* Unknown SGSN TLLI, create a new tlli_info */
498 uint32_t new_ptmsi;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200499 tlli_info = gbproxy_tlli_info_alloc(peer);
500 LOGP(DGPRS, LOGL_INFO, "Adding TLLI %08x to list (SGSN)\n",
501 parse_ctx->tlli);
502
503 gbproxy_attach_tlli_info(peer, now, tlli_info);
Jacob Erlbeck37fda772014-09-05 10:22:27 +0200504
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200505 /* Setup TLLIs */
506 tlli_info->sgsn_tlli.current = parse_ctx->tlli;
Jacob Erlbeck37fda772014-09-05 10:22:27 +0200507 tlli_info->tlli.current = parse_ctx->tlli;
508
509 if (!parse_ctx->new_ptmsi_enc)
510 return tlli_info;
511 /* A new P-TMSI has been signalled in the message */
512
513 if (!gprs_parse_mi_tmsi(parse_ctx->new_ptmsi_enc,
514 GSM48_TMSI_LEN, &new_ptmsi)) {
515 LOGP(DGPRS, LOGL_ERROR,
516 "Failed to parse new PTMSI (TLLI is %08x)\n",
517 parse_ctx->tlli);
518 return tlli_info;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200519 }
Jacob Erlbeck37fda772014-09-05 10:22:27 +0200520 LOGP(DGPRS, LOGL_INFO,
521 "Assigning new P-TMSI %08x\n", new_ptmsi);
522 /* Setup P-TMSIs */
523 tlli_info->sgsn_tlli.ptmsi = new_ptmsi;
524 tlli_info->tlli.ptmsi = new_ptmsi;
Jacob Erlbeck9114bee2014-08-19 12:21:01 +0200525 } else if (parse_ctx->tlli_enc && parse_ctx->llc && tlli_info) {
526 uint32_t bss_tlli = gbproxy_map_tlli(parse_ctx->tlli,
527 tlli_info, 1);
528 gbproxy_validate_tlli(&tlli_info->sgsn_tlli, parse_ctx->tlli, 1);
529 gbproxy_validate_tlli(&tlli_info->tlli, bss_tlli, 1);
530 gbproxy_touch_tlli(peer, tlli_info, now);
531 } else if (tlli_info) {
532 gbproxy_touch_tlli(peer, tlli_info, now);
533 }
534
535 if (parse_ctx->imsi && tlli_info && tlli_info->mi_data_len == 0) {
536 int enable_patching;
537 gbproxy_update_tlli_info(tlli_info,
538 parse_ctx->imsi, parse_ctx->imsi_len);
539
540 /* Check, whether the IMSI matches */
541 enable_patching = gbproxy_check_imsi(peer, parse_ctx->imsi,
542 parse_ctx->imsi_len);
543 if (enable_patching >= 0)
544 tlli_info->enable_patching = enable_patching;
545 }
546
547 return tlli_info;
548}
549
550void gbproxy_update_tlli_state_after(
551 struct gbproxy_peer *peer,
552 struct gbproxy_tlli_info *tlli_info,
553 time_t now,
554 struct gprs_gb_parse_context *parse_ctx)
555{
556 if (parse_ctx->invalidate_tlli)
557 gbproxy_unregister_tlli(peer, parse_ctx->tlli);
558
559 gbproxy_remove_stale_tllis(peer, now);
560}
561
562