Files
osmo-ggsn/gtp/queue.h
Pau Espin Pedrol 0585769741 libgtp: Define retransmit QUEUE_SIZE relative to PDP_MAX (increase)
QUEUE_SIZE holds the number of pending transmitted messages
which can be handled concurrently.
Current value was 1024, same as PDP contexts (PDP_MAX). However, that
seems to be a quite low amount, which can be filled under certain
conditions, for instance if recovery procedure is triggered on the GSN
which is running full (around PDP_MAX pdp contexts created).
In this scenario, the GSN would need to send around PDP_MAX concurrent
messages (DeletePDPContextReq), which means the queue would very likely
end up being full.
Hence, let's define QUEUE_SIZE based on PDP_MAX, and set it to twice the
size to make sure it won't be filled in extreme conditions.

Change-Id: I6034b0fab2b2e5962314c2fca2f893246ce5cf4f
2022-03-01 12:39:08 +01:00

76 lines
2.8 KiB
C

/*
* OsmoGGSN - Gateway GPRS Support Node
* Copyright (C) 2002 Mondru AB.
*
* The contents of this file may be used under the terms of the GNU
* General Public License Version 2, provided that the above copyright
* notice and this permission notice is included in all copies or
* substantial portions of the software.
*
*/
/*
* Queue.c
* Reliable delivery of signalling messages
*/
#ifndef _QUEUE_H
#define _QUEUE_H
#include <osmocom/core/linuxlist.h>
#include "gtp.h"
#define QUEUE_DEBUG 0 /* Print debug information */
#define QUEUE_SIZE (PDP_MAX*2) /* Size of retransmission queue */
#define QUEUE_HASH_SIZE 65536 /* Size of hash table (2^16) */
struct qmsg_t { /* Holder for queued packets */
int state; /* 0=empty, 1=full */
uint16_t seq; /* The sequence number */
uint8_t type; /* The type of packet */
void *cbp; /* Application specific pointer */
union gtp_packet p; /* The packet stored */
int l; /* Length of the packet */
int fd; /* Socket packet was sent to / received from */
struct sockaddr_in peer; /* Address packet was sent to / received from */
struct qmsg_t *seqnext; /* Pointer to next in sequence hash list */
int next; /* Pointer to the next in queue. -1: Last */
int prev; /* Pointer to the previous in queue. -1: First */
int this; /* Pointer to myself */
time_t timeout; /* When do we retransmit this packet? */
int retrans; /* How many times did we retransmit this? */
struct llist_head entry; /* Listed with other qmsg_t belonging to a pdp_t->qmsg_list_req */
};
struct queue_t {
struct qmsg_t qmsga[QUEUE_SIZE]; /* Array holding signalling messages */
void *hashseq[QUEUE_HASH_SIZE]; /* Hash array */
int next; /* Next location in queue to use */
int first; /* First packet in queue (oldest timeout) */
int last; /* Last packet in queue (youngest timeout) */
};
/* Allocates and initialises new queue structure */
int queue_new(struct queue_t **queue);
/* Deallocates queue structure */
int queue_free(struct queue_t *queue);
/* Find a new queue element. Return EOF if allready full */
int queue_newmsg(struct queue_t *queue, struct qmsg_t **qmsg,
struct sockaddr_in *peer, uint16_t seq);
/* Remove an element from the queue. */
int queue_freemsg(struct queue_t *queue, struct qmsg_t *qmsg);
/* Move an element to the back of the queue */
int queue_back(struct queue_t *queue, struct qmsg_t *qmsg);
/* Get the first element in the queue (oldest) */
int queue_getfirst(struct queue_t *queue, struct qmsg_t **qmsg);
/* Get the element with a particular sequence number */
int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
struct sockaddr_in *peer, uint16_t seq);
/* Free message based on sequence number */
int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer,
uint16_t seq, uint8_t * type, void **cbp);
#endif /* !_QUEUE_H */