aboutsummaryrefslogtreecommitdiffstats
path: root/gtp/queue.c
diff options
context:
space:
mode:
Diffstat (limited to 'gtp/queue.c')
-rw-r--r--gtp/queue.c402
1 files changed, 219 insertions, 183 deletions
diff --git a/gtp/queue.c b/gtp/queue.c
index 7fdf9df..02c18ec 100644
--- a/gtp/queue.c
+++ b/gtp/queue.c
@@ -29,224 +29,260 @@
#include "gtp.h"
#include "queue.h"
-int queue_print(struct queue_t *queue) {
- int n;
- printf("Queue: %x Next: %d First: %d Last: %d\n", (int) queue, queue->next, queue->first, queue->last);
- printf("# State seq next prev timeout retrans\n");
- for (n=0; n<QUEUE_SIZE; n++) {
- printf("%d %d %d %d %d %d %d\n",
- n,
- queue->qmsga[n].state,
- queue->qmsga[n].seq,
- queue->qmsga[n].next,
- queue->qmsga[n].prev,
- (int) queue->qmsga[n].timeout,
- queue->qmsga[n].retrans);
- }
- return 0;
+int queue_print(struct queue_t *queue)
+{
+ int n;
+ printf("Queue: %x Next: %d First: %d Last: %d\n", (int)queue,
+ queue->next, queue->first, queue->last);
+ printf("# State seq next prev timeout retrans\n");
+ for (n = 0; n < QUEUE_SIZE; n++) {
+ printf("%d %d %d %d %d %d %d\n",
+ n,
+ queue->qmsga[n].state,
+ queue->qmsga[n].seq,
+ queue->qmsga[n].next,
+ queue->qmsga[n].prev,
+ (int)queue->qmsga[n].timeout, queue->qmsga[n].retrans);
+ }
+ return 0;
}
-int queue_seqhash(struct sockaddr_in *peer, uint16_t seq) {
- /* With QUEUE_HASH_SIZE = 2^16 this describes all possible
- seq values. Thus we have perfect hash for the request queue.
- For the response queue we might have collisions, but not very
- often.
- For performance optimisation we should remove the modulus
- operator, but this is only valid for QUEUE_HASH_SIZE = 2^16 */
- return seq % QUEUE_HASH_SIZE;
+int queue_seqhash(struct sockaddr_in *peer, uint16_t seq)
+{
+ /* With QUEUE_HASH_SIZE = 2^16 this describes all possible
+ seq values. Thus we have perfect hash for the request queue.
+ For the response queue we might have collisions, but not very
+ often.
+ For performance optimisation we should remove the modulus
+ operator, but this is only valid for QUEUE_HASH_SIZE = 2^16 */
+ return seq % QUEUE_HASH_SIZE;
}
int queue_seqset(struct queue_t *queue, struct qmsg_t *qmsg,
- struct sockaddr_in *peer, uint16_t seq) {
- int hash = queue_seqhash(peer, seq);
- struct qmsg_t *qmsg2;
- struct qmsg_t *qmsg_prev = NULL;
-
- if (QUEUE_DEBUG) printf("Begin queue_seqset seq = %d\n", (int) seq);
- if (QUEUE_DEBUG) printf("SIZEOF PEER %d, *PEER %d\n", sizeof(peer), sizeof(*peer));
-
- qmsg->seq = seq;
- memcpy(&qmsg->peer, peer, sizeof(*peer));
-
- for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext)
- qmsg_prev = qmsg2;
- if (!qmsg_prev)
- queue->hashseq[hash] = qmsg;
- else
- qmsg_prev->seqnext = qmsg;
- if (QUEUE_DEBUG) printf("End queue_seqset\n");
- return 0;
-}
+ struct sockaddr_in *peer, uint16_t seq)
+{
+ int hash = queue_seqhash(peer, seq);
+ struct qmsg_t *qmsg2;
+ struct qmsg_t *qmsg_prev = NULL;
+
+ if (QUEUE_DEBUG)
+ printf("Begin queue_seqset seq = %d\n", (int)seq);
+ if (QUEUE_DEBUG)
+ printf("SIZEOF PEER %d, *PEER %d\n", sizeof(peer),
+ sizeof(*peer));
+ qmsg->seq = seq;
+ memcpy(&qmsg->peer, peer, sizeof(*peer));
-int queue_seqdel(struct queue_t *queue, struct qmsg_t *qmsg) {
- int hash = queue_seqhash(&qmsg->peer, qmsg->seq);
- struct qmsg_t *qmsg2;
- struct qmsg_t *qmsg_prev = NULL;
- if (QUEUE_DEBUG) printf("Begin queue_seqdel seq = %d\n", (int) qmsg->seq);
-
- for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
- if (qmsg == qmsg) {
- if (!qmsg_prev)
- queue->hashseq[hash] = qmsg2->seqnext;
- else
- qmsg_prev->seqnext = qmsg2->seqnext;
- if (QUEUE_DEBUG) printf("End queue_seqset: SEQ found\n");
- return 0;
- }
- qmsg_prev = qmsg2;
- }
- printf("End queue_seqset: SEQ not found\n");
- return EOF; /* End of linked list and not found */
+ for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext)
+ qmsg_prev = qmsg2;
+ if (!qmsg_prev)
+ queue->hashseq[hash] = qmsg;
+ else
+ qmsg_prev->seqnext = qmsg;
+ if (QUEUE_DEBUG)
+ printf("End queue_seqset\n");
+ return 0;
}
+int queue_seqdel(struct queue_t *queue, struct qmsg_t *qmsg)
+{
+ int hash = queue_seqhash(&qmsg->peer, qmsg->seq);
+ struct qmsg_t *qmsg2;
+ struct qmsg_t *qmsg_prev = NULL;
+ if (QUEUE_DEBUG)
+ printf("Begin queue_seqdel seq = %d\n", (int)qmsg->seq);
+
+ for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
+ if (qmsg == qmsg) {
+ if (!qmsg_prev)
+ queue->hashseq[hash] = qmsg2->seqnext;
+ else
+ qmsg_prev->seqnext = qmsg2->seqnext;
+ if (QUEUE_DEBUG)
+ printf("End queue_seqset: SEQ found\n");
+ return 0;
+ }
+ qmsg_prev = qmsg2;
+ }
+ printf("End queue_seqset: SEQ not found\n");
+ return EOF; /* End of linked list and not found */
+}
/* Allocates and initialises new queue structure */
-int queue_new(struct queue_t **queue) {
- if (QUEUE_DEBUG) printf("queue_new\n");
- *queue = calloc(1, sizeof(struct queue_t));
- (*queue)->next = 0;
- (*queue)->first = -1;
- (*queue)->last = -1;
-
- if (QUEUE_DEBUG) queue_print(*queue);
- if (*queue) return 0;
- else return EOF;
+int queue_new(struct queue_t **queue)
+{
+ if (QUEUE_DEBUG)
+ printf("queue_new\n");
+ *queue = calloc(1, sizeof(struct queue_t));
+ (*queue)->next = 0;
+ (*queue)->first = -1;
+ (*queue)->last = -1;
+
+ if (QUEUE_DEBUG)
+ queue_print(*queue);
+ if (*queue)
+ return 0;
+ else
+ return EOF;
}
/* Deallocates queue structure */
-int queue_free(struct queue_t *queue) {
- if (QUEUE_DEBUG) printf("queue_free\n");
- if (QUEUE_DEBUG) queue_print(queue);
- free(queue);
- return 0;
+int queue_free(struct queue_t *queue)
+{
+ if (QUEUE_DEBUG)
+ printf("queue_free\n");
+ if (QUEUE_DEBUG)
+ queue_print(queue);
+ free(queue);
+ return 0;
}
int queue_newmsg(struct queue_t *queue, struct qmsg_t **qmsg,
- struct sockaddr_in *peer, uint16_t seq) {
- if (QUEUE_DEBUG) printf("queue_newmsg %d\n", (int) seq);
- if (queue->qmsga[queue->next].state == 1) {
- return EOF; /* Queue is full */
- }
- else {
- *qmsg = &queue->qmsga[queue->next];
- queue_seqset(queue, *qmsg, peer, seq);
- (*qmsg)->state = 1; /* Space taken */
- (*qmsg)->this = queue->next;
- (*qmsg)->next=-1; /* End of the queue */
- (*qmsg)->prev=queue->last; /* Link to the previous */
- if (queue->last != -1)
- queue->qmsga[queue->last].next=queue->next; /* Link previous to us */
- queue->last = queue->next; /* End of queue */
- if (queue->first == -1) queue->first = queue->next;
- queue->next = (queue->next+1) % QUEUE_SIZE; /* Increment */
- if (QUEUE_DEBUG) queue_print(queue);
- return 0;
- }
+ struct sockaddr_in *peer, uint16_t seq)
+{
+ if (QUEUE_DEBUG)
+ printf("queue_newmsg %d\n", (int)seq);
+ if (queue->qmsga[queue->next].state == 1) {
+ return EOF; /* Queue is full */
+ } else {
+ *qmsg = &queue->qmsga[queue->next];
+ queue_seqset(queue, *qmsg, peer, seq);
+ (*qmsg)->state = 1; /* Space taken */
+ (*qmsg)->this = queue->next;
+ (*qmsg)->next = -1; /* End of the queue */
+ (*qmsg)->prev = queue->last; /* Link to the previous */
+ if (queue->last != -1)
+ queue->qmsga[queue->last].next = queue->next; /* Link previous to us */
+ queue->last = queue->next; /* End of queue */
+ if (queue->first == -1)
+ queue->first = queue->next;
+ queue->next = (queue->next + 1) % QUEUE_SIZE; /* Increment */
+ if (QUEUE_DEBUG)
+ queue_print(queue);
+ return 0;
+ }
}
-int queue_freemsg(struct queue_t *queue, struct qmsg_t *qmsg) {
- if (QUEUE_DEBUG) printf("queue_freemsg\n");
- if (qmsg->state != 1) {
- return EOF; /* Not in queue */
- }
+int queue_freemsg(struct queue_t *queue, struct qmsg_t *qmsg)
+{
+ if (QUEUE_DEBUG)
+ printf("queue_freemsg\n");
+ if (qmsg->state != 1) {
+ return EOF; /* Not in queue */
+ }
- queue_seqdel(queue, qmsg);
+ queue_seqdel(queue, qmsg);
- if (qmsg->next == -1) /* Are we the last in queue? */
- queue->last = qmsg->prev;
- else
- queue->qmsga[qmsg->next].prev = qmsg->prev;
-
- if (qmsg->prev == -1) /* Are we the first in queue? */
- queue->first = qmsg->next;
- else
- queue->qmsga[qmsg->prev].next = qmsg->next;
+ if (qmsg->next == -1) /* Are we the last in queue? */
+ queue->last = qmsg->prev;
+ else
+ queue->qmsga[qmsg->next].prev = qmsg->prev;
- memset(qmsg, 0, sizeof(struct qmsg_t)); /* Just to be safe */
+ if (qmsg->prev == -1) /* Are we the first in queue? */
+ queue->first = qmsg->next;
+ else
+ queue->qmsga[qmsg->prev].next = qmsg->next;
- if (QUEUE_DEBUG) queue_print(queue);
+ memset(qmsg, 0, sizeof(struct qmsg_t)); /* Just to be safe */
- return 0;
+ if (QUEUE_DEBUG)
+ queue_print(queue);
+
+ return 0;
}
-int queue_back(struct queue_t *queue, struct qmsg_t *qmsg) {
- if (QUEUE_DEBUG) printf("queue_back\n");
- if (qmsg->state != 1) {
- return EOF; /* Not in queue */
- }
-
- /* Insert stuff to maintain hash table */
-
- if (qmsg->next != -1) {/* Only swop if there are others */
- queue->qmsga[qmsg->next].prev = qmsg->prev;
- queue->first = qmsg->next;
-
- qmsg->next = -1;
- qmsg->prev = queue->last;
- if (queue->last != -1) queue->qmsga[queue->last].next = qmsg->this;
- queue->last = qmsg->this;
- }
- if (QUEUE_DEBUG) queue_print(queue);
- return 0;
+int queue_back(struct queue_t *queue, struct qmsg_t *qmsg)
+{
+ if (QUEUE_DEBUG)
+ printf("queue_back\n");
+ if (qmsg->state != 1) {
+ return EOF; /* Not in queue */
+ }
+
+ /* Insert stuff to maintain hash table */
+
+ if (qmsg->next != -1) { /* Only swop if there are others */
+ queue->qmsga[qmsg->next].prev = qmsg->prev;
+ queue->first = qmsg->next;
+
+ qmsg->next = -1;
+ qmsg->prev = queue->last;
+ if (queue->last != -1)
+ queue->qmsga[queue->last].next = qmsg->this;
+ queue->last = qmsg->this;
+ }
+ if (QUEUE_DEBUG)
+ queue_print(queue);
+ return 0;
}
/* Get the element with a particular sequence number */
-int queue_getfirst(struct queue_t *queue, struct qmsg_t **qmsg) {
- /*printf("queue_getfirst\n");*/
- if (queue->first == -1) {
- *qmsg = NULL;
- return EOF; /* End of queue = queue is empty. */
- }
- *qmsg = &queue->qmsga[queue->first];
- if (QUEUE_DEBUG) queue_print(queue);
- return 0;
+int queue_getfirst(struct queue_t *queue, struct qmsg_t **qmsg)
+{
+ /*printf("queue_getfirst\n"); */
+ if (queue->first == -1) {
+ *qmsg = NULL;
+ return EOF; /* End of queue = queue is empty. */
+ }
+ *qmsg = &queue->qmsga[queue->first];
+ if (QUEUE_DEBUG)
+ queue_print(queue);
+ return 0;
}
int queue_getseqx(struct queue_t *queue, struct qmsg_t **qmsg,
- struct sockaddr_in *peer, uint16_t seq) {
- int n;
- if (QUEUE_DEBUG) printf("queue_getseq, %d\n", (int) seq);
- if (QUEUE_DEBUG) queue_print(queue);
- for (n=0; n<QUEUE_SIZE; n++) {
- if ((queue->qmsga[n].seq == seq) &&
- (!memcmp(&queue->qmsga[n].peer, peer, sizeof(*peer)))) {
- *qmsg = &queue->qmsga[n];
- return 0;
- }
- }
- return EOF; /* Not found */
+ struct sockaddr_in *peer, uint16_t seq)
+{
+ int n;
+ if (QUEUE_DEBUG)
+ printf("queue_getseq, %d\n", (int)seq);
+ if (QUEUE_DEBUG)
+ queue_print(queue);
+ for (n = 0; n < QUEUE_SIZE; n++) {
+ if ((queue->qmsga[n].seq == seq) &&
+ (!memcmp(&queue->qmsga[n].peer, peer, sizeof(*peer)))) {
+ *qmsg = &queue->qmsga[n];
+ return 0;
+ }
+ }
+ return EOF; /* Not found */
}
int queue_seqget(struct queue_t *queue, struct qmsg_t **qmsg,
- struct sockaddr_in *peer, uint16_t seq) {
- int hash = queue_seqhash(peer, seq);
- struct qmsg_t *qmsg2;
- if (QUEUE_DEBUG) printf("Begin queue_seqget seq = %d\n", (int) seq);
- for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
- if ((qmsg2->seq == seq) &&
- (!memcmp(&qmsg2->peer, peer, sizeof(*peer)))) {
- *qmsg = qmsg2;
- if (QUEUE_DEBUG) printf("End queue_seqget. Found\n");
- return 0;
- }
- }
- if (QUEUE_DEBUG) printf("End queue_seqget. Not found\n");
- return EOF; /* End of linked list and not found */
+ struct sockaddr_in *peer, uint16_t seq)
+{
+ int hash = queue_seqhash(peer, seq);
+ struct qmsg_t *qmsg2;
+ if (QUEUE_DEBUG)
+ printf("Begin queue_seqget seq = %d\n", (int)seq);
+ for (qmsg2 = queue->hashseq[hash]; qmsg2; qmsg2 = qmsg2->seqnext) {
+ if ((qmsg2->seq == seq) &&
+ (!memcmp(&qmsg2->peer, peer, sizeof(*peer)))) {
+ *qmsg = qmsg2;
+ if (QUEUE_DEBUG)
+ printf("End queue_seqget. Found\n");
+ return 0;
+ }
+ }
+ if (QUEUE_DEBUG)
+ printf("End queue_seqget. Not found\n");
+ return EOF; /* End of linked list and not found */
}
-int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer,
- uint16_t seq, uint8_t *type, void **cbp) {
- struct qmsg_t *qmsg;
- if (queue_seqget(queue, &qmsg, peer, seq)) {
- *cbp = NULL;
- *type = 0;
- return EOF;
- }
- *cbp = qmsg->cbp;
- *type = qmsg->type;
- if (queue_freemsg(queue, qmsg)) {
- return EOF;
- }
- return 0;
+int queue_freemsg_seq(struct queue_t *queue, struct sockaddr_in *peer,
+ uint16_t seq, uint8_t * type, void **cbp)
+{
+ struct qmsg_t *qmsg;
+ if (queue_seqget(queue, &qmsg, peer, seq)) {
+ *cbp = NULL;
+ *type = 0;
+ return EOF;
+ }
+ *cbp = qmsg->cbp;
+ *type = qmsg->type;
+ if (queue_freemsg(queue, qmsg)) {
+ return EOF;
+ }
+ return 0;
}