Coverage Report

Created: 2023-09-25 07:12

/src/open5gs/lib/gtp/xact.c
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright (C) 2019 by Sukchan Lee <acetcom@gmail.com>
3
 * Copyright (C) 2022 by sysmocom - s.f.m.c. GmbH <info@sysmocom.de>
4
 *
5
 * This file is part of Open5GS.
6
 *
7
 * This program is free software: you can redistribute it and/or modify
8
 * it under the terms of the GNU Affero General Public License as published by
9
 * the Free Software Foundation, either version 3 of the License, or
10
 * (at your option) any later version.
11
 *
12
 * This program is distributed in the hope that it will be useful,
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 * GNU General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License
18
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
19
 */
20
21
#include "ogs-gtp.h"
22
#include "ogs-app.h"
23
24
typedef enum {
25
    GTP_XACT_UNKNOWN_STAGE,
26
    GTP_XACT_INITIAL_STAGE,
27
    GTP_XACT_INTERMEDIATE_STAGE,
28
    GTP_XACT_FINAL_STAGE,
29
} ogs_gtp_xact_stage_t;
30
31
static int ogs_gtp_xact_initialized = 0;
32
static uint32_t g_xact_id = 0;
33
34
static OGS_POOL(pool, ogs_gtp_xact_t);
35
36
static ogs_gtp_xact_t *ogs_gtp_xact_remote_create(ogs_gtp_node_t *gnode, uint8_t gtp_version, uint32_t sqn);
37
static ogs_gtp_xact_stage_t ogs_gtp2_xact_get_stage(uint8_t type, uint32_t xid);
38
static ogs_gtp_xact_stage_t ogs_gtp1_xact_get_stage(uint8_t type, uint32_t xid);
39
static int ogs_gtp_xact_delete(ogs_gtp_xact_t *xact);
40
static int ogs_gtp_xact_update_rx(ogs_gtp_xact_t *xact, uint8_t type);
41
42
static void response_timeout(void *data);
43
static void holding_timeout(void *data);
44
45
int ogs_gtp_xact_init(void)
46
0
{
47
0
    ogs_assert(ogs_gtp_xact_initialized == 0);
48
49
0
    ogs_pool_init(&pool, ogs_app()->pool.xact);
50
51
0
    g_xact_id = 0;
52
53
0
    ogs_gtp_xact_initialized = 1;
54
55
0
    return OGS_OK;
56
0
}
57
58
void ogs_gtp_xact_final(void)
59
0
{
60
0
    ogs_assert(ogs_gtp_xact_initialized == 1);
61
62
0
    ogs_pool_final(&pool);
63
64
0
    ogs_gtp_xact_initialized = 0;
65
0
}
66
67
ogs_gtp_xact_t *ogs_gtp1_xact_local_create(ogs_gtp_node_t *gnode,
68
        ogs_gtp1_header_t *hdesc, ogs_pkbuf_t *pkbuf,
69
        void (*cb)(ogs_gtp_xact_t *xact, void *data), void *data)
70
0
{
71
0
    int rv;
72
0
    char buf[OGS_ADDRSTRLEN];
73
0
    ogs_gtp_xact_t *xact = NULL;
74
75
0
    ogs_assert(gnode);
76
0
    ogs_assert(hdesc);
77
78
0
    ogs_pool_alloc(&pool, &xact);
79
0
    ogs_assert(xact);
80
0
    memset(xact, 0, sizeof *xact);
81
0
    xact->index = ogs_pool_index(&pool, xact);
82
83
0
    xact->gtp_version = 1;
84
0
    xact->org = OGS_GTP_LOCAL_ORIGINATOR;
85
0
    xact->xid = OGS_NEXT_ID(g_xact_id,
86
0
            OGS_GTP1_MIN_XACT_ID, OGS_GTP1_MAX_XACT_ID);
87
0
    xact->gnode = gnode;
88
0
    xact->cb = cb;
89
0
    xact->data = data;
90
91
    /* 7.6 "The T3-RESPONSE timer shall be started when a signalling request
92
     * message (for which a response has been defined) is sent." */
93
0
    if (hdesc->type != OGS_GTP1_RAN_INFORMATION_RELAY_TYPE) {
94
0
        xact->tm_response = ogs_timer_add(
95
0
                ogs_app()->timer_mgr, response_timeout, xact);
96
0
        ogs_assert(xact->tm_response);
97
0
        xact->response_rcount = ogs_app()->time.message.gtp.n3_response_rcount;
98
0
    }
99
100
0
    xact->tm_holding = ogs_timer_add(
101
0
            ogs_app()->timer_mgr, holding_timeout, xact);
102
0
    ogs_assert(xact->tm_holding);
103
0
    xact->holding_rcount = ogs_app()->time.message.gtp.n3_holding_rcount;
104
105
0
    ogs_list_add(&xact->gnode->local_list, xact);
106
107
0
    rv = ogs_gtp1_xact_update_tx(xact, hdesc, pkbuf);
108
0
    if (rv != OGS_OK) {
109
0
        ogs_error("ogs_gtp_xact_update_tx(rv=%d) failed", (int)rv);
110
0
        ogs_gtp_xact_delete(xact);
111
0
        return NULL;
112
0
    }
113
114
0
    ogs_debug("[%d] LOCAL Create  peer [%s]:%d",
115
0
            xact->xid,
116
0
            OGS_ADDR(&gnode->addr, buf),
117
0
            OGS_PORT(&gnode->addr));
118
119
0
    return xact;
120
0
}
121
122
ogs_gtp_xact_t *ogs_gtp_xact_local_create(ogs_gtp_node_t *gnode,
123
        ogs_gtp2_header_t *hdesc, ogs_pkbuf_t *pkbuf,
124
        void (*cb)(ogs_gtp_xact_t *xact, void *data), void *data)
125
0
{
126
0
    int rv;
127
0
    char buf[OGS_ADDRSTRLEN];
128
0
    ogs_gtp_xact_t *xact = NULL;
129
130
0
    ogs_assert(gnode);
131
0
    ogs_assert(hdesc);
132
133
0
    ogs_pool_alloc(&pool, &xact);
134
0
    ogs_assert(xact);
135
0
    memset(xact, 0, sizeof *xact);
136
0
    xact->index = ogs_pool_index(&pool, xact);
137
138
0
    xact->gtp_version = 2;
139
0
    xact->org = OGS_GTP_LOCAL_ORIGINATOR;
140
0
    xact->xid = OGS_NEXT_ID(g_xact_id,
141
0
            OGS_GTP_MIN_XACT_ID, OGS_GTP_CMD_XACT_ID);
142
0
    if (hdesc->type == OGS_GTP2_MODIFY_BEARER_COMMAND_TYPE ||
143
0
        hdesc->type == OGS_GTP2_DELETE_BEARER_COMMAND_TYPE ||
144
0
        hdesc->type == OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE) {
145
0
        xact->xid |= OGS_GTP_CMD_XACT_ID;
146
0
    }
147
0
    xact->gnode = gnode;
148
0
    xact->cb = cb;
149
0
    xact->data = data;
150
151
0
    xact->tm_response = ogs_timer_add(
152
0
            ogs_app()->timer_mgr, response_timeout, xact);
153
0
    ogs_assert(xact->tm_response);
154
0
    xact->response_rcount = ogs_app()->time.message.gtp.n3_response_rcount,
155
156
0
    xact->tm_holding = ogs_timer_add(
157
0
            ogs_app()->timer_mgr, holding_timeout, xact);
158
0
    ogs_assert(xact->tm_holding);
159
0
    xact->holding_rcount = ogs_app()->time.message.gtp.n3_holding_rcount,
160
161
0
    ogs_list_add(&xact->gnode->local_list, xact);
162
163
0
    rv = ogs_gtp_xact_update_tx(xact, hdesc, pkbuf);
164
0
    if (rv != OGS_OK) {
165
0
        ogs_error("ogs_gtp_xact_update_tx(rv=%d) failed", (int)rv);
166
0
        ogs_gtp_xact_delete(xact);
167
0
        return NULL;
168
0
    }
169
170
0
    ogs_debug("[%d] LOCAL Create  peer [%s]:%d",
171
0
            xact->xid,
172
0
            OGS_ADDR(&gnode->addr, buf),
173
0
            OGS_PORT(&gnode->addr));
174
175
0
    return xact;
176
0
}
177
178
static ogs_gtp_xact_t *ogs_gtp_xact_remote_create(ogs_gtp_node_t *gnode, uint8_t gtp_version, uint32_t sqn)
179
0
{
180
0
    char buf[OGS_ADDRSTRLEN];
181
0
    ogs_gtp_xact_t *xact = NULL;
182
183
0
    ogs_assert(gnode);
184
185
0
    ogs_pool_alloc(&pool, &xact);
186
0
    ogs_assert(xact);
187
0
    memset(xact, 0, sizeof *xact);
188
0
    xact->index = ogs_pool_index(&pool, xact);
189
190
0
    xact->gtp_version = gtp_version;
191
0
    xact->org = OGS_GTP_REMOTE_ORIGINATOR;
192
0
    xact->xid = (gtp_version == 1) ?
193
0
            OGS_GTP1_SQN_TO_XID(sqn) : OGS_GTP2_SQN_TO_XID(sqn);
194
0
    xact->gnode = gnode;
195
196
0
    xact->tm_response = ogs_timer_add(
197
0
            ogs_app()->timer_mgr, response_timeout, xact);
198
0
    ogs_assert(xact->tm_response);
199
0
    xact->response_rcount = ogs_app()->time.message.gtp.n3_response_rcount,
200
201
0
    xact->tm_holding = ogs_timer_add(
202
0
            ogs_app()->timer_mgr, holding_timeout, xact);
203
0
    ogs_assert(xact->tm_holding);
204
0
    xact->holding_rcount = ogs_app()->time.message.gtp.n3_holding_rcount,
205
206
0
    ogs_list_add(&xact->gnode->remote_list, xact);
207
208
0
    ogs_debug("[%d] REMOTE Create  peer [%s]:%d",
209
0
            xact->xid,
210
0
            OGS_ADDR(&gnode->addr, buf),
211
0
            OGS_PORT(&gnode->addr));
212
213
0
    return xact;
214
0
}
215
216
ogs_gtp_xact_t *ogs_gtp_xact_cycle(ogs_gtp_xact_t *xact)
217
0
{
218
0
    return ogs_pool_cycle(&pool, xact);
219
0
}
220
221
void ogs_gtp_xact_delete_all(ogs_gtp_node_t *gnode)
222
0
{
223
0
    ogs_gtp_xact_t *xact = NULL, *next_xact = NULL;
224
225
0
    ogs_list_for_each_safe(&gnode->local_list, next_xact, xact)
226
0
        ogs_gtp_xact_delete(xact);
227
0
    ogs_list_for_each_safe(&gnode->remote_list, next_xact, xact)
228
0
        ogs_gtp_xact_delete(xact);
229
0
}
230
231
int ogs_gtp1_xact_update_tx(ogs_gtp_xact_t *xact,
232
        ogs_gtp1_header_t *hdesc, ogs_pkbuf_t *pkbuf)
233
0
{
234
0
    char buf[OGS_ADDRSTRLEN];
235
0
    ogs_gtp_xact_stage_t stage;
236
0
    ogs_gtp1_header_t *h = NULL;
237
0
    int gtp_hlen = 0;
238
239
0
    ogs_assert(xact);
240
0
    ogs_assert(xact->gnode);
241
0
    ogs_assert(hdesc);
242
0
    ogs_assert(pkbuf);
243
244
0
    ogs_debug("[%d] %s UPD TX-%d  peer [%s]:%d",
245
0
            xact->xid,
246
0
            xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
247
0
            hdesc->type,
248
0
            OGS_ADDR(&xact->gnode->addr, buf),
249
0
            OGS_PORT(&xact->gnode->addr));
250
251
0
    stage = ogs_gtp1_xact_get_stage(hdesc->type, xact->xid);
252
0
    if (xact->org == OGS_GTP_LOCAL_ORIGINATOR) {
253
0
        switch (stage) {
254
0
        case GTP_XACT_INITIAL_STAGE:
255
0
            if (xact->step != 0) {
256
0
                ogs_error("invalid step[%d]", xact->step);
257
0
                ogs_pkbuf_free(pkbuf);
258
0
                return OGS_ERROR;
259
0
            }
260
0
            break;
261
262
0
        case GTP_XACT_INTERMEDIATE_STAGE:
263
0
            ogs_expect(0);
264
0
            ogs_pkbuf_free(pkbuf);
265
0
            return OGS_ERROR;
266
267
0
        case GTP_XACT_FINAL_STAGE:
268
0
            if (xact->step != 2) {
269
0
                ogs_error("invalid step[%d]", xact->step);
270
0
                ogs_pkbuf_free(pkbuf);
271
0
                return OGS_ERROR;
272
0
            }
273
0
            break;
274
275
0
        default:
276
0
            ogs_assert_if_reached();
277
0
            break;
278
0
        }
279
0
    } else if (xact->org == OGS_GTP_REMOTE_ORIGINATOR) {
280
0
        switch (stage) {
281
0
        case GTP_XACT_INITIAL_STAGE:
282
0
            ogs_expect(0);
283
0
            ogs_pkbuf_free(pkbuf);
284
0
            return OGS_ERROR;
285
286
0
        case GTP_XACT_INTERMEDIATE_STAGE:
287
0
        case GTP_XACT_FINAL_STAGE:
288
0
            if (xact->step != 1) {
289
0
                ogs_error("invalid step[%d]", xact->step);
290
0
                ogs_pkbuf_free(pkbuf);
291
0
                return OGS_ERROR;
292
0
            }
293
0
            break;
294
295
0
        default:
296
0
            ogs_error("invalid stage[%d]", stage);
297
0
            ogs_pkbuf_free(pkbuf);
298
0
            return OGS_ERROR;
299
0
        }
300
0
    } else {
301
0
        ogs_error("invalid org[%d]", xact->org);
302
0
        ogs_pkbuf_free(pkbuf);
303
0
        return OGS_ERROR;
304
0
    }
305
306
0
    gtp_hlen = OGS_GTPV1C_HEADER_LEN;
307
308
309
0
    ogs_pkbuf_push(pkbuf, gtp_hlen);
310
0
    h = (ogs_gtp1_header_t *)pkbuf->data;
311
0
    memset(h, 0, gtp_hlen);
312
313
0
    h->version = 1;
314
0
    h->type = hdesc->type;
315
0
    h->pt = 1; /* GTP */
316
0
    h->teid = htobe32(hdesc->teid);
317
318
0
    h->s = 1;
319
0
    h->sqn = OGS_GTP1_XID_TO_SQN(xact->xid);
320
0
    h->length = htobe16(pkbuf->len - 8);
321
322
    /* Save Message type and packet of this step */
323
0
    xact->seq[xact->step].type = h->type;
324
0
    xact->seq[xact->step].pkbuf = pkbuf;
325
326
    /* Step */
327
0
    xact->step++;
328
329
0
    return OGS_OK;
330
0
}
331
332
int ogs_gtp_xact_update_tx(ogs_gtp_xact_t *xact,
333
        ogs_gtp2_header_t *hdesc, ogs_pkbuf_t *pkbuf)
334
0
{
335
0
    char buf[OGS_ADDRSTRLEN];
336
0
    ogs_gtp_xact_stage_t stage;
337
0
    ogs_gtp2_header_t *h = NULL;
338
0
    int gtp_hlen = 0;
339
340
0
    ogs_assert(xact);
341
0
    ogs_assert(xact->gnode);
342
0
    ogs_assert(hdesc);
343
0
    ogs_assert(pkbuf);
344
345
0
    ogs_debug("[%d] %s UPD TX-%d  peer [%s]:%d",
346
0
            xact->xid,
347
0
            xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
348
0
            hdesc->type,
349
0
            OGS_ADDR(&xact->gnode->addr, buf),
350
0
            OGS_PORT(&xact->gnode->addr));
351
352
0
    stage = ogs_gtp2_xact_get_stage(hdesc->type, xact->xid);
353
0
    if (xact->org == OGS_GTP_LOCAL_ORIGINATOR) {
354
0
        switch (stage) {
355
0
        case GTP_XACT_INITIAL_STAGE:
356
0
            if (xact->step != 0) {
357
0
                ogs_error("invalid step[%d]", xact->step);
358
0
                ogs_pkbuf_free(pkbuf);
359
0
                return OGS_ERROR;
360
0
            }
361
0
            break;
362
363
0
        case GTP_XACT_INTERMEDIATE_STAGE:
364
0
            ogs_expect(0);
365
0
            ogs_pkbuf_free(pkbuf);
366
0
            return OGS_ERROR;
367
368
0
        case GTP_XACT_FINAL_STAGE:
369
0
            if (xact->step != 2) {
370
0
                ogs_error("invalid step[%d]", xact->step);
371
0
                ogs_pkbuf_free(pkbuf);
372
0
                return OGS_ERROR;
373
0
            }
374
0
            break;
375
376
0
        default:
377
0
            ogs_assert_if_reached();
378
0
            break;
379
0
        }
380
0
    } else if (xact->org == OGS_GTP_REMOTE_ORIGINATOR) {
381
0
        switch (stage) {
382
0
        case GTP_XACT_INITIAL_STAGE:
383
0
            ogs_expect(0);
384
0
            ogs_pkbuf_free(pkbuf);
385
0
            return OGS_ERROR;
386
387
0
        case GTP_XACT_INTERMEDIATE_STAGE:
388
0
        case GTP_XACT_FINAL_STAGE:
389
0
            if (xact->step != 1) {
390
0
                ogs_error("invalid step[%d]", xact->step);
391
0
                ogs_pkbuf_free(pkbuf);
392
0
                return OGS_ERROR;
393
0
            }
394
0
            break;
395
396
0
        default:
397
0
            ogs_error("invalid stage[%d]", stage);
398
0
            ogs_pkbuf_free(pkbuf);
399
0
            return OGS_ERROR;
400
0
        }
401
0
    } else {
402
0
        ogs_error("invalid org[%d]", xact->org);
403
0
        ogs_pkbuf_free(pkbuf);
404
0
        return OGS_ERROR;
405
0
    }
406
407
0
    if (hdesc->type > OGS_GTP2_VERSION_NOT_SUPPORTED_INDICATION_TYPE) {
408
0
        gtp_hlen = OGS_GTPV2C_HEADER_LEN;
409
0
    } else {
410
0
        gtp_hlen = OGS_GTPV2C_HEADER_LEN - OGS_GTP2_TEID_LEN;
411
0
    }
412
413
0
    ogs_pkbuf_push(pkbuf, gtp_hlen);
414
0
    h = (ogs_gtp2_header_t *)pkbuf->data;
415
0
    memset(h, 0, gtp_hlen);
416
417
0
    h->version = 2;
418
0
    h->type = hdesc->type;
419
420
0
    if (hdesc->type > OGS_GTP2_VERSION_NOT_SUPPORTED_INDICATION_TYPE) {
421
0
        h->teid_presence = 1;
422
0
        h->teid = htobe32(hdesc->teid);
423
0
        h->sqn = OGS_GTP2_XID_TO_SQN(xact->xid);
424
0
    } else {
425
0
        h->teid_presence = 0;
426
0
        h->sqn_only = OGS_GTP2_XID_TO_SQN(xact->xid);
427
0
    }
428
0
    h->length = htobe16(pkbuf->len - 4);
429
430
    /* Save Message type and packet of this step */
431
0
    xact->seq[xact->step].type = h->type;
432
0
    xact->seq[xact->step].pkbuf = pkbuf;
433
434
    /* Step */
435
0
    xact->step++;
436
437
0
    return OGS_OK;
438
0
}
439
440
static int ogs_gtp_xact_update_rx(ogs_gtp_xact_t *xact, uint8_t type)
441
0
{
442
0
    char buf[OGS_ADDRSTRLEN];
443
0
    ogs_gtp_xact_stage_t stage;
444
445
0
    ogs_debug("[%d] %s UPD RX-%d  peer [%s]:%d",
446
0
            xact->xid,
447
0
            xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
448
0
            type,
449
0
            OGS_ADDR(&xact->gnode->addr, buf),
450
0
            OGS_PORT(&xact->gnode->addr));
451
452
0
    if (xact->gtp_version == 1)
453
0
        stage = ogs_gtp1_xact_get_stage(type, xact->xid);
454
0
    else
455
0
        stage = ogs_gtp2_xact_get_stage(type, xact->xid);
456
457
0
    if (xact->org == OGS_GTP_LOCAL_ORIGINATOR) {
458
0
        switch (stage) {
459
0
        case GTP_XACT_INITIAL_STAGE:
460
0
            ogs_expect(0);
461
0
            return OGS_ERROR;
462
463
0
        case GTP_XACT_INTERMEDIATE_STAGE:
464
0
            if (xact->seq[1].type == type) {
465
0
                ogs_pkbuf_t *pkbuf = NULL;
466
467
0
                if (xact->step != 2 && xact->step != 3) {
468
0
                    ogs_error("invalid step[%d]", xact->step);
469
0
                    ogs_pkbuf_free(pkbuf);
470
0
                    return OGS_ERROR;
471
0
                }
472
473
0
                pkbuf = xact->seq[2].pkbuf;
474
0
                if (pkbuf) {
475
0
                    if (xact->tm_holding)
476
0
                        ogs_timer_start(xact->tm_holding,
477
0
                                ogs_app()->time.message.
478
0
                                    gtp.t3_holding_duration);
479
480
0
                    ogs_warn("[%d] %s Request Duplicated. Retransmit!"
481
0
                            " for step %d type %d peer [%s]:%d",
482
0
                            xact->xid,
483
0
                            xact->org == OGS_GTP_LOCAL_ORIGINATOR ?
484
0
                                "LOCAL " : "REMOTE",
485
0
                            xact->step, type,
486
0
                            OGS_ADDR(&xact->gnode->addr,
487
0
                                buf),
488
0
                            OGS_PORT(&xact->gnode->addr));
489
0
                    ogs_expect(OGS_OK == ogs_gtp_sendto(xact->gnode, pkbuf));
490
0
                } else {
491
0
                    ogs_warn("[%d] %s Request Duplicated. Discard!"
492
0
                            " for step %d type %d peer [%s]:%d",
493
0
                            xact->xid,
494
0
                            xact->org == OGS_GTP_LOCAL_ORIGINATOR ?
495
0
                                "LOCAL " : "REMOTE",
496
0
                            xact->step, type,
497
0
                            OGS_ADDR(&xact->gnode->addr,
498
0
                                buf),
499
0
                            OGS_PORT(&xact->gnode->addr));
500
0
                }
501
502
0
                return OGS_RETRY;
503
0
            }
504
505
0
            if (xact->step != 1) {
506
0
                ogs_error("invalid step[%d]", xact->step);
507
0
                return OGS_ERROR;
508
0
            }
509
510
0
            if (xact->tm_holding)
511
0
                ogs_timer_start(xact->tm_holding,
512
0
                        ogs_app()->time.message.gtp.t3_holding_duration);
513
514
0
            break;
515
516
0
        case GTP_XACT_FINAL_STAGE:
517
0
            if (xact->step != 1) {
518
0
                ogs_error("invalid step[%d]", xact->step);
519
0
                return OGS_ERROR;
520
0
            }
521
0
            break;
522
523
0
        default:
524
0
            ogs_error("invalid stage[%d]", stage);
525
0
            return OGS_ERROR;
526
0
        }
527
0
    } else if (xact->org == OGS_GTP_REMOTE_ORIGINATOR) {
528
0
        switch (stage) {
529
0
        case GTP_XACT_INITIAL_STAGE:
530
0
            if (xact->seq[0].type == type) {
531
0
                ogs_pkbuf_t *pkbuf = NULL;
532
533
0
                if (xact->step != 1 && xact->step != 2) {
534
0
                    ogs_error("invalid step[%d]", xact->step);
535
0
                    return OGS_ERROR;
536
0
                }
537
538
0
                pkbuf = xact->seq[1].pkbuf;
539
0
                if (pkbuf) {
540
0
                    if (xact->tm_holding)
541
0
                        ogs_timer_start(xact->tm_holding,
542
0
                                ogs_app()->time.message.
543
0
                                    gtp.t3_holding_duration);
544
545
0
                    ogs_warn("[%d] %s Request Duplicated. Retransmit!"
546
0
                            " for step %d type %d peer [%s]:%d",
547
0
                            xact->xid,
548
0
                            xact->org == OGS_GTP_LOCAL_ORIGINATOR ?
549
0
                                "LOCAL " : "REMOTE",
550
0
                            xact->step, type,
551
0
                            OGS_ADDR(&xact->gnode->addr,
552
0
                                buf),
553
0
                            OGS_PORT(&xact->gnode->addr));
554
0
                    ogs_expect(OGS_OK == ogs_gtp_sendto(xact->gnode, pkbuf));
555
0
                } else {
556
0
                    ogs_warn("[%d] %s Request Duplicated. Discard!"
557
0
                            " for step %d type %d peer [%s]:%d",
558
0
                            xact->xid,
559
0
                            xact->org == OGS_GTP_LOCAL_ORIGINATOR ?
560
0
                                "LOCAL " : "REMOTE",
561
0
                            xact->step, type,
562
0
                            OGS_ADDR(&xact->gnode->addr,
563
0
                                buf),
564
0
                            OGS_PORT(&xact->gnode->addr));
565
0
                }
566
567
0
                return OGS_RETRY;
568
0
            }
569
570
0
            if (xact->step != 0) {
571
0
                ogs_error("invalid step[%d]", xact->step);
572
0
                return OGS_ERROR;
573
0
            }
574
0
            if (xact->tm_holding)
575
0
                ogs_timer_start(xact->tm_holding,
576
0
                        ogs_app()->time.message.gtp.t3_holding_duration);
577
578
0
            break;
579
580
0
        case GTP_XACT_INTERMEDIATE_STAGE:
581
0
            ogs_expect(0);
582
0
            return OGS_ERROR;
583
584
0
        case GTP_XACT_FINAL_STAGE:
585
0
            if (xact->step != 2) {
586
0
                ogs_error("invalid step[%d]", xact->step);
587
0
                return OGS_ERROR;
588
0
            }
589
590
            /* continue */
591
0
            break;
592
593
0
        default:
594
0
            ogs_error("invalid stage[%d]", stage);
595
0
            return OGS_ERROR;
596
0
        }
597
0
    } else {
598
0
        ogs_error("invalid org[%d]", xact->org);
599
0
        return OGS_ERROR;
600
0
    }
601
602
0
    if (xact->tm_response)
603
0
        ogs_timer_stop(xact->tm_response);
604
605
    /* Save Message type of this step */
606
0
    xact->seq[xact->step].type = type;
607
608
    /* Step */
609
0
    xact->step++;
610
611
0
    return OGS_OK;
612
0
}
613
614
615
int ogs_gtp_xact_commit(ogs_gtp_xact_t *xact)
616
0
{
617
0
    char buf[OGS_ADDRSTRLEN];
618
619
0
    uint8_t type;
620
0
    ogs_pkbuf_t *pkbuf = NULL;
621
0
    ogs_gtp_xact_stage_t stage;
622
623
0
    ogs_assert(xact);
624
0
    ogs_assert(xact->gnode);
625
626
0
    ogs_debug("[%d] %s Commit  peer [%s]:%d",
627
0
            xact->xid,
628
0
            xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
629
0
            OGS_ADDR(&xact->gnode->addr, buf),
630
0
            OGS_PORT(&xact->gnode->addr));
631
632
0
    type = xact->seq[xact->step-1].type;
633
0
    if (xact->gtp_version == 1)
634
0
        stage = ogs_gtp1_xact_get_stage(type, xact->xid);
635
0
    else
636
0
        stage = ogs_gtp2_xact_get_stage(type, xact->xid);
637
638
0
    if (xact->org == OGS_GTP_LOCAL_ORIGINATOR) {
639
0
        switch (stage) {
640
0
        case GTP_XACT_INITIAL_STAGE:
641
0
            if (xact->step != 1) {
642
0
                ogs_error("invalid step[%d]", xact->step);
643
0
                ogs_gtp_xact_delete(xact);
644
0
                return OGS_ERROR;
645
0
            }
646
647
0
            if (xact->tm_response)
648
0
                ogs_timer_start(xact->tm_response,
649
0
                        ogs_app()->time.message.gtp.t3_response_duration);
650
651
0
            break;
652
653
0
        case GTP_XACT_INTERMEDIATE_STAGE:
654
0
            ogs_expect(0);
655
0
            ogs_gtp_xact_delete(xact);
656
0
            return OGS_ERROR;
657
658
0
        case GTP_XACT_FINAL_STAGE:
659
0
            if (xact->step != 2 && xact->step != 3) {
660
0
                ogs_error("invalid step[%d]", xact->step);
661
0
                ogs_gtp_xact_delete(xact);
662
0
                return OGS_ERROR;
663
0
            }
664
0
            if (xact->step == 2) {
665
0
                ogs_gtp_xact_delete(xact);
666
0
                return OGS_OK;
667
0
            }
668
669
0
            break;
670
671
0
        default:
672
0
            ogs_error("invalid stage[%d]", stage);
673
0
            ogs_gtp_xact_delete(xact);
674
0
            return OGS_ERROR;
675
0
        }
676
0
    } else if (xact->org == OGS_GTP_REMOTE_ORIGINATOR) {
677
0
        switch (stage) {
678
0
        case GTP_XACT_INITIAL_STAGE:
679
0
            ogs_expect(0);
680
0
            ogs_gtp_xact_delete(xact);
681
0
            return OGS_ERROR;
682
683
0
        case GTP_XACT_INTERMEDIATE_STAGE:
684
0
            if (xact->step != 2) {
685
0
                ogs_error("invalid step[%d]", xact->step);
686
0
                ogs_gtp_xact_delete(xact);
687
0
                return OGS_ERROR;
688
0
            }
689
0
            if (xact->tm_response)
690
0
                ogs_timer_start(xact->tm_response,
691
0
                        ogs_app()->time.message.gtp.t3_response_duration);
692
693
0
            break;
694
695
0
        case GTP_XACT_FINAL_STAGE:
696
0
            if (xact->step != 2 && xact->step != 3) {
697
0
                ogs_error("invalid step[%d]", xact->step);
698
0
                ogs_gtp_xact_delete(xact);
699
0
                return OGS_ERROR;
700
0
            }
701
0
            if (xact->step == 3) {
702
0
                ogs_gtp_xact_delete(xact);
703
0
                return OGS_OK;
704
0
            }
705
706
0
            break;
707
708
0
        default:
709
0
            ogs_error("invalid stage[%d]", stage);
710
0
            ogs_gtp_xact_delete(xact);
711
0
            return OGS_ERROR;
712
0
        }
713
0
    } else {
714
0
        ogs_error("invalid org[%d]", xact->org);
715
0
        ogs_gtp_xact_delete(xact);
716
0
        return OGS_ERROR;
717
0
    }
718
719
0
    pkbuf = xact->seq[xact->step-1].pkbuf;
720
0
    ogs_assert(pkbuf);
721
722
0
    ogs_expect(OGS_OK == ogs_gtp_sendto(xact->gnode, pkbuf));
723
724
0
    return OGS_OK;
725
0
}
726
727
static void response_timeout(void *data)
728
0
{
729
0
    char buf[OGS_ADDRSTRLEN];
730
0
    ogs_gtp_xact_t *xact = data;
731
732
0
    ogs_assert(xact);
733
0
    ogs_assert(xact->gnode);
734
735
0
    ogs_debug("[%d] %s Response Timeout "
736
0
            "for step %d type %d peer [%s]:%d",
737
0
            xact->xid,
738
0
            xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
739
0
            xact->step, xact->seq[xact->step-1].type,
740
0
            OGS_ADDR(&xact->gnode->addr, buf),
741
0
            OGS_PORT(&xact->gnode->addr));
742
743
0
    if (--xact->response_rcount > 0) {
744
0
        ogs_pkbuf_t *pkbuf = NULL;
745
746
0
        if (xact->tm_response)
747
0
            ogs_timer_start(xact->tm_response,
748
0
                    ogs_app()->time.message.gtp.t3_response_duration);
749
750
0
        pkbuf = xact->seq[xact->step-1].pkbuf;
751
0
        ogs_assert(pkbuf);
752
753
0
        ogs_expect(OGS_OK == ogs_gtp_sendto(xact->gnode, pkbuf));
754
0
    } else {
755
0
        ogs_warn("[%d] %s No Reponse. Give up! "
756
0
                "for step %d type %d peer [%s]:%d",
757
0
                xact->xid,
758
0
                xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
759
0
                xact->step, xact->seq[xact->step-1].type,
760
0
                OGS_ADDR(&xact->gnode->addr, buf),
761
0
                OGS_PORT(&xact->gnode->addr));
762
763
0
        if (xact->cb)
764
0
            xact->cb(xact, xact->data);
765
766
0
        ogs_gtp_xact_delete(xact);
767
0
    }
768
0
}
769
770
static void holding_timeout(void *data)
771
0
{
772
0
    char buf[OGS_ADDRSTRLEN];
773
0
    ogs_gtp_xact_t *xact = data;
774
775
0
    ogs_assert(xact);
776
0
    ogs_assert(xact->gnode);
777
778
0
    ogs_debug("[%d] %s Holding Timeout "
779
0
            "for step %d type %d peer [%s]:%d",
780
0
            xact->xid,
781
0
            xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
782
0
            xact->step, xact->seq[xact->step-1].type,
783
0
            OGS_ADDR(&xact->gnode->addr, buf),
784
0
            OGS_PORT(&xact->gnode->addr));
785
786
0
    if (--xact->holding_rcount > 0) {
787
0
        if (xact->tm_holding)
788
0
            ogs_timer_start(xact->tm_holding,
789
0
                    ogs_app()->time.message.gtp.t3_holding_duration);
790
0
    } else {
791
0
        ogs_debug("[%d] %s Delete Transaction "
792
0
                "for step %d type %d peer [%s]:%d",
793
0
                xact->xid,
794
0
                xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
795
0
                xact->step, xact->seq[xact->step-1].type,
796
0
                OGS_ADDR(&xact->gnode->addr, buf),
797
0
                OGS_PORT(&xact->gnode->addr));
798
0
        ogs_gtp_xact_delete(xact);
799
0
    }
800
0
}
801
802
int ogs_gtp1_xact_receive(
803
        ogs_gtp_node_t *gnode, ogs_gtp1_header_t *h, ogs_gtp_xact_t **xact)
804
0
{
805
0
    int rv;
806
0
    char buf[OGS_ADDRSTRLEN];
807
808
0
    uint8_t type;
809
0
    uint32_t sqn, xid;
810
0
    ogs_gtp_xact_stage_t stage;
811
0
    ogs_list_t *list = NULL;
812
0
    ogs_gtp_xact_t *new = NULL;
813
814
0
    ogs_assert(gnode);
815
0
    ogs_assert(h);
816
817
0
    type = h->type;
818
819
0
    if (!h->s) {
820
0
        ogs_error("ogs_gtp_xact_update_rx() failed, pkt has no SQN");
821
0
        return OGS_ERROR;
822
0
    }
823
0
    sqn = h->sqn;
824
825
0
    xid = OGS_GTP1_SQN_TO_XID(sqn);
826
0
    stage = ogs_gtp1_xact_get_stage(type, xid);
827
828
0
    switch (stage) {
829
0
    case GTP_XACT_INITIAL_STAGE:
830
0
        list = &gnode->remote_list;
831
0
        break;
832
0
    case GTP_XACT_INTERMEDIATE_STAGE:
833
0
        list = &gnode->local_list;
834
0
        break;
835
0
    case GTP_XACT_FINAL_STAGE:
836
0
        list = &gnode->local_list; // FIXME: is this correct?
837
0
        break;
838
0
    default:
839
0
        ogs_error("[%d] Unexpected type %u from GTPv1 peer [%s]:%d",
840
0
                xid, type, OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
841
0
        return OGS_ERROR;
842
0
    }
843
844
0
    ogs_assert(list);
845
0
    ogs_list_for_each(list, new) {
846
0
        if (new->gtp_version == 1 && new->xid == xid) {
847
0
            ogs_debug("[%d] %s Find GTPv%u peer [%s]:%d",
848
0
                    new->xid,
849
0
                    new->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
850
0
                    new->gtp_version,
851
0
                    OGS_ADDR(&gnode->addr, buf),
852
0
                    OGS_PORT(&gnode->addr));
853
0
            break;
854
0
        }
855
0
    }
856
857
0
    ogs_debug("[%d] Cannot find xact type %u from GTPv1 peer [%s]:%d",
858
0
            xid, type, OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
859
860
0
    if (!new)
861
0
        new = ogs_gtp_xact_remote_create(gnode, 1, sqn);
862
0
    ogs_assert(new);
863
864
0
    ogs_debug("[%d] %s Receive peer [%s]:%d",
865
0
            new->xid,
866
0
            new->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
867
0
            OGS_ADDR(&gnode->addr, buf),
868
0
            OGS_PORT(&gnode->addr));
869
870
0
    rv = ogs_gtp_xact_update_rx(new, type);
871
0
    if (rv == OGS_ERROR) {
872
0
        ogs_error("ogs_gtp_xact_update_rx() failed");
873
0
        ogs_gtp_xact_delete(new);
874
0
        return rv;
875
0
    } else if (rv == OGS_RETRY) {
876
0
        return rv;
877
0
    }
878
879
0
    *xact = new;
880
0
    return rv;
881
0
}
882
883
int ogs_gtp_xact_receive(
884
        ogs_gtp_node_t *gnode, ogs_gtp2_header_t *h, ogs_gtp_xact_t **xact)
885
0
{
886
0
    int rv;
887
0
    char buf[OGS_ADDRSTRLEN];
888
889
0
    uint8_t type;
890
0
    uint32_t sqn, xid;
891
0
    ogs_gtp_xact_stage_t stage;
892
0
    ogs_list_t *list = NULL;
893
0
    ogs_gtp_xact_t *new = NULL;
894
895
0
    ogs_assert(gnode);
896
0
    ogs_assert(h);
897
898
0
    type = h->type;
899
900
0
    if (h->teid_presence) sqn = h->sqn;
901
0
    else sqn = h->sqn_only;
902
903
0
    xid = OGS_GTP2_SQN_TO_XID(sqn);
904
0
    stage = ogs_gtp2_xact_get_stage(type, xid);
905
906
0
    switch (stage) {
907
0
    case GTP_XACT_INITIAL_STAGE:
908
0
        list = &gnode->remote_list;
909
0
        break;
910
0
    case GTP_XACT_INTERMEDIATE_STAGE:
911
0
        list = &gnode->local_list;
912
0
        break;
913
0
    case GTP_XACT_FINAL_STAGE:
914
0
        if (xid & OGS_GTP_CMD_XACT_ID) {
915
0
            if (type == OGS_GTP2_MODIFY_BEARER_FAILURE_INDICATION_TYPE ||
916
0
                type == OGS_GTP2_DELETE_BEARER_FAILURE_INDICATION_TYPE ||
917
0
                type == OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE) {
918
0
                list = &gnode->local_list;
919
0
            } else {
920
0
                list = &gnode->remote_list;
921
0
            }
922
0
        } else {
923
0
            list = &gnode->local_list;
924
0
        }
925
0
        break;
926
0
    default:
927
0
        ogs_error("[%d] Unexpected type %u from GTPv2 peer [%s]:%d",
928
0
                xid, type, OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
929
0
        return OGS_ERROR;
930
0
    }
931
932
0
    ogs_assert(list);
933
0
    ogs_list_for_each(list, new) {
934
0
        if (new->gtp_version == 2 && new->xid == xid) {
935
0
            ogs_debug("[%d] %s Find GTPv%u peer [%s]:%d",
936
0
                    new->xid,
937
0
                    new->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
938
0
                    new->gtp_version,
939
0
                    OGS_ADDR(&gnode->addr, buf),
940
0
                    OGS_PORT(&gnode->addr));
941
0
            break;
942
0
        }
943
0
    }
944
945
0
    ogs_debug("[%d] Cannot find xact type %u from GTPv2 peer [%s]:%d",
946
0
            xid, type,
947
0
            OGS_ADDR(&gnode->addr, buf), OGS_PORT(&gnode->addr));
948
949
0
    if (!new)
950
0
        new = ogs_gtp_xact_remote_create(gnode, 2, sqn);
951
0
    ogs_assert(new);
952
953
0
    ogs_debug("[%d] %s Receive peer [%s]:%d",
954
0
            new->xid,
955
0
            new->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
956
0
            OGS_ADDR(&gnode->addr, buf),
957
0
            OGS_PORT(&gnode->addr));
958
959
0
    rv = ogs_gtp_xact_update_rx(new, type);
960
0
    if (rv == OGS_ERROR) {
961
0
        ogs_error("ogs_gtp_xact_update_rx() failed");
962
0
        ogs_gtp_xact_delete(new);
963
0
        return rv;
964
0
    } else if (rv == OGS_RETRY) {
965
0
        return rv;
966
0
    }
967
968
0
    *xact = new;
969
0
    return rv;
970
0
}
971
972
static ogs_gtp_xact_stage_t ogs_gtp1_xact_get_stage(uint8_t type, uint32_t xid)
973
0
{
974
0
    ogs_gtp_xact_stage_t stage = GTP_XACT_UNKNOWN_STAGE;
975
976
0
    switch (type) {
977
0
    case OGS_GTP1_ECHO_REQUEST_TYPE:
978
0
    case OGS_GTP1_NODE_ALIVE_REQUEST_TYPE:
979
0
    case OGS_GTP1_REDIRECTION_REQUEST_TYPE:
980
0
    case OGS_GTP1_CREATE_PDP_CONTEXT_REQUEST_TYPE:
981
0
    case OGS_GTP1_UPDATE_PDP_CONTEXT_REQUEST_TYPE:
982
0
    case OGS_GTP1_DELETE_PDP_CONTEXT_REQUEST_TYPE:
983
0
    case OGS_GTP1_INITIATE_PDP_CONTEXT_ACTIVATION_REQUEST_TYPE:
984
0
    case OGS_GTP1_PDU_NOTIFICATION_REQUEST_TYPE:
985
0
    case OGS_GTP1_PDU_NOTIFICATION_REJECT_REQUEST_TYPE:
986
0
    case OGS_GTP1_SEND_ROUTEING_INFORMATION_FOR_GPRS_REQUEST_TYPE:
987
0
    case OGS_GTP1_FAILURE_REPORT_REQUEST_TYPE:
988
0
    case OGS_GTP1_NOTE_MS_GPRS_PRESENT_REQUEST_TYPE:
989
0
    case OGS_GTP1_IDENTIFICATION_REQUEST_TYPE:
990
0
    case OGS_GTP1_SGSN_CONTEXT_REQUEST_TYPE:
991
0
    case OGS_GTP1_FORWARD_RELOCATION_REQUEST_TYPE:
992
0
    case OGS_GTP1_RELOCATION_CANCEL_REQUEST_TYPE:
993
0
    case OGS_GTP1_UE_REGISTRATION_QUERY_REQUEST_TYPE:
994
0
    case OGS_GTP1_RAN_INFORMATION_RELAY_TYPE:
995
0
        stage = GTP_XACT_INITIAL_STAGE;
996
0
        break;
997
0
    case OGS_GTP1_ECHO_RESPONSE_TYPE:
998
0
    case OGS_GTP1_NODE_ALIVE_RESPONSE_TYPE:
999
0
    case OGS_GTP1_REDIRECTION_RESPONSE_TYPE:
1000
0
    case OGS_GTP1_CREATE_PDP_CONTEXT_RESPONSE_TYPE:
1001
0
    case OGS_GTP1_UPDATE_PDP_CONTEXT_RESPONSE_TYPE:
1002
0
    case OGS_GTP1_DELETE_PDP_CONTEXT_RESPONSE_TYPE:
1003
0
    case OGS_GTP1_INITIATE_PDP_CONTEXT_ACTIVATION_RESPONSE_TYPE:
1004
0
    case OGS_GTP1_PDU_NOTIFICATION_RESPONSE_TYPE:
1005
0
    case OGS_GTP1_PDU_NOTIFICATION_REJECT_RESPONSE_TYPE:
1006
0
    case OGS_GTP1_SEND_ROUTEING_INFORMATION_FOR_GPRS_RESPONSE_TYPE:
1007
0
    case OGS_GTP1_FAILURE_REPORT_RESPONSE_TYPE:
1008
0
    case OGS_GTP1_NOTE_MS_GPRS_PRESENT_RESPONSE_TYPE:
1009
0
    case OGS_GTP1_IDENTIFICATION_RESPONSE_TYPE:
1010
0
    case OGS_GTP1_SGSN_CONTEXT_RESPONSE_TYPE:
1011
0
    case OGS_GTP1_FORWARD_RELOCATION_RESPONSE_TYPE:
1012
0
    case OGS_GTP1_RELOCATION_CANCEL_RESPONSE_TYPE:
1013
0
    case OGS_GTP1_UE_REGISTRATION_QUERY_RESPONSE_TYPE:
1014
0
        stage = GTP_XACT_FINAL_STAGE;
1015
0
        break;
1016
1017
0
    default:
1018
0
        ogs_error("Not implemented GTPv1 Message Type(%d)", type);
1019
0
        break;
1020
0
    }
1021
1022
0
    return stage;
1023
0
}
1024
1025
/* TS 29.274 Table 6.1-1 */
1026
static ogs_gtp_xact_stage_t ogs_gtp2_xact_get_stage(uint8_t type, uint32_t xid)
1027
0
{
1028
0
    ogs_gtp_xact_stage_t stage = GTP_XACT_UNKNOWN_STAGE;
1029
1030
0
    switch (type) {
1031
0
    case OGS_GTP2_ECHO_REQUEST_TYPE:
1032
0
    case OGS_GTP2_CREATE_SESSION_REQUEST_TYPE:
1033
0
    case OGS_GTP2_MODIFY_BEARER_REQUEST_TYPE:
1034
0
    case OGS_GTP2_DELETE_SESSION_REQUEST_TYPE:
1035
0
    case OGS_GTP2_CHANGE_NOTIFICATION_REQUEST_TYPE:
1036
0
    case OGS_GTP2_REMOTE_UE_REPORT_NOTIFICATION_TYPE:
1037
0
    case OGS_GTP2_MODIFY_BEARER_COMMAND_TYPE:
1038
0
    case OGS_GTP2_DELETE_BEARER_COMMAND_TYPE:
1039
0
    case OGS_GTP2_BEARER_RESOURCE_COMMAND_TYPE:
1040
0
    case OGS_GTP2_TRACE_SESSION_ACTIVATION_TYPE:
1041
0
    case OGS_GTP2_TRACE_SESSION_DEACTIVATION_TYPE:
1042
0
    case OGS_GTP2_STOP_PAGING_INDICATION_TYPE:
1043
0
    case OGS_GTP2_DELETE_PDN_CONNECTION_SET_REQUEST_TYPE:
1044
0
    case OGS_GTP2_PGW_DOWNLINK_TRIGGERING_NOTIFICATION_TYPE:
1045
0
    case OGS_GTP2_CREATE_FORWARDING_TUNNEL_REQUEST_TYPE:
1046
0
    case OGS_GTP2_SUSPEND_NOTIFICATION_TYPE:
1047
0
    case OGS_GTP2_RESUME_NOTIFICATION_TYPE:
1048
0
    case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
1049
0
    case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_REQUEST_TYPE:
1050
0
    case OGS_GTP2_RELEASE_ACCESS_BEARERS_REQUEST_TYPE:
1051
0
    case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_TYPE:
1052
0
    case OGS_GTP2_PGW_RESTART_NOTIFICATION_TYPE:
1053
0
    case OGS_GTP2_UPDATE_PDN_CONNECTION_SET_REQUEST_TYPE:
1054
0
    case OGS_GTP2_MODIFY_ACCESS_BEARERS_REQUEST_TYPE:
1055
0
        stage = GTP_XACT_INITIAL_STAGE;
1056
0
        break;
1057
0
    case OGS_GTP2_CREATE_BEARER_REQUEST_TYPE:
1058
0
    case OGS_GTP2_UPDATE_BEARER_REQUEST_TYPE:
1059
0
    case OGS_GTP2_DELETE_BEARER_REQUEST_TYPE:
1060
0
        if (xid & OGS_GTP_CMD_XACT_ID)
1061
0
            stage = GTP_XACT_INTERMEDIATE_STAGE;
1062
0
        else
1063
0
            stage = GTP_XACT_INITIAL_STAGE;
1064
0
        break;
1065
0
    case OGS_GTP2_ECHO_RESPONSE_TYPE:
1066
0
    case OGS_GTP2_VERSION_NOT_SUPPORTED_INDICATION_TYPE:
1067
0
    case OGS_GTP2_CREATE_SESSION_RESPONSE_TYPE:
1068
0
    case OGS_GTP2_MODIFY_BEARER_RESPONSE_TYPE:
1069
0
    case OGS_GTP2_DELETE_SESSION_RESPONSE_TYPE:
1070
0
    case OGS_GTP2_CHANGE_NOTIFICATION_RESPONSE_TYPE:
1071
0
    case OGS_GTP2_REMOTE_UE_REPORT_ACKNOWLEDGE_TYPE:
1072
0
    case OGS_GTP2_MODIFY_BEARER_FAILURE_INDICATION_TYPE:
1073
0
    case OGS_GTP2_DELETE_BEARER_FAILURE_INDICATION_TYPE:
1074
0
    case OGS_GTP2_BEARER_RESOURCE_FAILURE_INDICATION_TYPE:
1075
0
    case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_FAILURE_INDICATION_TYPE:
1076
0
    case OGS_GTP2_CREATE_BEARER_RESPONSE_TYPE:
1077
0
    case OGS_GTP2_UPDATE_BEARER_RESPONSE_TYPE:
1078
0
    case OGS_GTP2_DELETE_BEARER_RESPONSE_TYPE:
1079
0
    case OGS_GTP2_DELETE_PDN_CONNECTION_SET_RESPONSE_TYPE:
1080
0
    case OGS_GTP2_PGW_DOWNLINK_TRIGGERING_ACKNOWLEDGE_TYPE:
1081
0
    case OGS_GTP2_CREATE_FORWARDING_TUNNEL_RESPONSE_TYPE:
1082
0
    case OGS_GTP2_SUSPEND_ACKNOWLEDGE_TYPE:
1083
0
    case OGS_GTP2_RESUME_ACKNOWLEDGE_TYPE:
1084
0
    case OGS_GTP2_CREATE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE:
1085
0
    case OGS_GTP2_DELETE_INDIRECT_DATA_FORWARDING_TUNNEL_RESPONSE_TYPE:
1086
0
    case OGS_GTP2_RELEASE_ACCESS_BEARERS_RESPONSE_TYPE:
1087
0
    case OGS_GTP2_DOWNLINK_DATA_NOTIFICATION_ACKNOWLEDGE_TYPE:
1088
0
    case OGS_GTP2_PGW_RESTART_NOTIFICATION_ACKNOWLEDGE_TYPE:
1089
0
    case OGS_GTP2_UPDATE_PDN_CONNECTION_SET_RESPONSE_TYPE:
1090
0
    case OGS_GTP2_MODIFY_ACCESS_BEARERS_RESPONSE_TYPE:
1091
0
        stage = GTP_XACT_FINAL_STAGE;
1092
0
        break;
1093
1094
0
    default:
1095
0
        ogs_error("Not implemented GTPv2 Message Type(%d)", type);
1096
0
        break;
1097
0
    }
1098
1099
0
    return stage;
1100
0
}
1101
1102
void ogs_gtp_xact_associate(ogs_gtp_xact_t *xact1, ogs_gtp_xact_t *xact2)
1103
0
{
1104
0
    ogs_assert(xact1);
1105
0
    ogs_assert(xact2);
1106
1107
0
    ogs_assert(xact1->assoc_xact == NULL);
1108
0
    ogs_assert(xact2->assoc_xact == NULL);
1109
1110
0
    xact1->assoc_xact = xact2;
1111
0
    xact2->assoc_xact = xact1;
1112
0
}
1113
1114
void ogs_gtp_xact_deassociate(ogs_gtp_xact_t *xact1, ogs_gtp_xact_t *xact2)
1115
0
{
1116
0
    ogs_assert(xact1);
1117
0
    ogs_assert(xact2);
1118
1119
0
    ogs_assert(xact1->assoc_xact != NULL);
1120
0
    ogs_assert(xact2->assoc_xact != NULL);
1121
1122
0
    xact1->assoc_xact = NULL;
1123
0
    xact2->assoc_xact = NULL;
1124
0
}
1125
1126
static int ogs_gtp_xact_delete(ogs_gtp_xact_t *xact)
1127
0
{
1128
0
    char buf[OGS_ADDRSTRLEN];
1129
1130
0
    ogs_assert(xact);
1131
0
    ogs_assert(xact->gnode);
1132
1133
0
    ogs_debug("[%d] %s Delete  peer [%s]:%d",
1134
0
            xact->xid,
1135
0
            xact->org == OGS_GTP_LOCAL_ORIGINATOR ? "LOCAL " : "REMOTE",
1136
0
            OGS_ADDR(&xact->gnode->addr, buf),
1137
0
            OGS_PORT(&xact->gnode->addr));
1138
1139
0
    if (xact->seq[0].pkbuf)
1140
0
        ogs_pkbuf_free(xact->seq[0].pkbuf);
1141
0
    if (xact->seq[1].pkbuf)
1142
0
        ogs_pkbuf_free(xact->seq[1].pkbuf);
1143
0
    if (xact->seq[2].pkbuf)
1144
0
        ogs_pkbuf_free(xact->seq[2].pkbuf);
1145
1146
0
    if (xact->tm_response)
1147
0
        ogs_timer_delete(xact->tm_response);
1148
0
    if (xact->tm_holding)
1149
0
        ogs_timer_delete(xact->tm_holding);
1150
1151
0
    if (xact->assoc_xact)
1152
0
        ogs_gtp_xact_deassociate(xact, xact->assoc_xact);
1153
1154
0
    ogs_list_remove(xact->org == OGS_GTP_LOCAL_ORIGINATOR ?
1155
0
            &xact->gnode->local_list : &xact->gnode->remote_list, xact);
1156
0
    ogs_pool_free(&pool, xact);
1157
1158
0
    return OGS_OK;
1159
0
}