aboutsummaryrefslogtreecommitdiffstats
path: root/gtp/queue.h
blob: 1e95676bb49eb3baa69e8f9a0c1379381e9c9f27 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/* 
 *  OpenGGSN - 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.
 * 
 *  The initial developer of the original code is
 *  Jens Jakobsen <jj@openggsn.org>
 * 
 *  Contributor(s):
 * 
 */

/*
 * Queue.c
 * Reliable delivery of signalling messages
 */

#ifndef _QUEUE_H
#define _QUEUE_H

#define QUEUE_DEBUG 0    /* Print debug information */

#define QUEUE_SIZE 1024  /* 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 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 */