diff options
author | Daiki Ueno <ueno@gnu.org> | 2020-10-18 07:17:38 +0200 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2020-10-18 19:18:09 +0200 |
commit | e748eac332661781a010b92cb2ce6d6c080d0b15 (patch) | |
tree | 8e4447a7bcfd80f55cf38b226025a248d1cc22fc | |
parent | 90f14691e1a269bf3247537e6da374f472b64d25 (diff) | |
download | gnutls-e748eac332661781a010b92cb2ce6d6c080d0b15.tar.gz |
serv: replace our own list implementation with Gnulib's gl_list
Signed-off-by: Daiki Ueno <ueno@gnu.org>
-rw-r--r-- | bootstrap.conf | 2 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/list.h | 446 | ||||
-rw-r--r-- | src/serv.c | 125 | ||||
-rw-r--r-- | src/udp-serv.c | 1 |
5 files changed, 85 insertions, 491 deletions
diff --git a/bootstrap.conf b/bootstrap.conf index f8de3d4be1..36b6d58f8e 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -36,7 +36,7 @@ unictype/category-all unictype/property-default-ignorable-code-point unictype/pr " src_modules=" -accept bind close connect getaddrinfo getpass gettext-h arpa_inet inet_ntop inet_pton listen minmax parse-datetime progname read-file recv recvfrom select send sendto servent setsockopt shutdown socket sockets socklen inttypes +accept bind close connect getaddrinfo getpass gettext-h arpa_inet inet_ntop inet_pton inttypes listen linked-list minmax parse-datetime progname read-file recv recvfrom select send sendto servent setsockopt shutdown socket sockets socklen xalloc xlist " # Build prerequisites diff --git a/src/Makefile.am b/src/Makefile.am index 94b701a512..450700a3d0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -140,7 +140,7 @@ nodist_libcmd_ocsp_la_SOURCES = ocsptool-args.h ocsptool-args.c endif gnutls_serv_SOURCES = \ - list.h serv.c \ + serv.c \ udp-serv.c udp-serv.h \ common.h common.c \ certtool-common.h diff --git a/src/list.h b/src/list.h deleted file mode 100644 index 1b3c9e4635..0000000000 --- a/src/list.h +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (C) 2001,2002 Paul Sheer - * - * This file is part of GnuTLS. - * - * GnuTLS is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuTLS is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef GNUTLS_SRC_LIST_H -#define GNUTLS_SRC_LIST_H - -/* - SOAP: - - Academics always want to implement hash tables (i.e. dictionaries), - singly or doubly linked lists, and queues, because ... well ... they - know how. - - These datatypes are nonsense for the following reasons: - hash tables: Hash tables are a mapping of some - string to some data, where that data is going to - be accessed COMPLETELY RANDOMLY. This is what it - is for. However it is extremely rare to have a - large number of data elements which really are - being accessed in a completely random way. - - lists: appending and searching through lists is always - slow because these operations search all the way - through the list. - - queues: what's the difference between a queue and a list? - very little really. - - The system implemented here is a doubly linked list with previous - search index that can be appended or prepended with no overhead, - implemented entirely in macros. It is hence as versatile as a - doubly/singly linked list or queue and blazingly fast. Hence doing - sequential searches where the next search result is likely to be - closely indexed to the previous (usual case), is efficient. - - Of course this doesn't mean you should use this as a hash table - where you REALLY need a hash table. - -*/ - -/********** example usage **********/ -/* - -#include "list.h" - -extern void free (void *x); -extern char *strdup (char *s); - -// consider a list of elements containing an `int' and a `char *' -LIST_TYPE_DECLARE (names, char *s; int i;); - -// for sorting, to compare elements -static int cm (names **a, names **b) -{ - return strcmp ((*a)->s, (*b)->s); -} - -// to free the contents of an element -static void free_item (names *a) -{ - free (a->s); - a->s = 0; // say - a->i = 0; // say -} - -int main (int argc, char **argv) -{ -// you can separate these into LIST_TYPE_DECLARE(), LIST_DECLARE() and linit() if needed. - LIST_DECLARE_INIT (l, names, free_item); - names *j; - - lappend (l); - l.tail->s = strdup ("hello"); - l.tail->i = 1; - lappend (l); - l.tail->s = strdup ("there"); - l.tail->i = 2; - lappend (l); - l.tail->s = strdup ("my"); - l.tail->i = 3; - lappend (l); - l.tail->s = strdup ("name"); - l.tail->i = 4; - lappend (l); - l.tail->s = strdup ("is"); - l.tail->i = 5; - lappend (l); - l.tail->s = strdup ("fred"); - l.tail->i = 6; - - printf ("%ld\n\n", lcount (l)); - lloopforward (l, j, printf ("%d %s\n", j->i, j->s)); - printf ("\n"); - - lsort (l, cm); - lloopforward (l, j, printf ("%d %s\n", j->i, j->s)); - - lloopreverse (l, j, if (j->i <= 3) ldeleteinc (l, j);); - - printf ("\n"); - lloopforward (l, j, printf ("%d %s\n", j->i, j->s)); - - ldeleteall (l); - - printf ("\n"); - lloopforward (l, j, printf ("%d %s\n", j->i, j->s)); - return 0; -} - -*/ - -/* the `search' member points to the last found. - this speeds up repeated searches on the same list-item, - the consecutive list-item, or the pre-consecutive list-item. - this obviates the need for a hash table for 99% of - cercumstances the time */ -struct list { - long length; - long item_size; - struct list_item { - struct list_item *next; - struct list_item *prev; - char data[1]; - } *head, *tail, *search; - void (*free_func) (struct list_item *); -}; - -/* declare a list of type `x', also called `x' having members `typelist' */ - -#define LIST_TYPE_DECLARE(type,typelist) \ - typedef struct type { \ - struct type *next; \ - struct type *prev; \ - typelist \ - } type - -#define LIST_DECLARE(l,type) \ - struct { \ - long length; \ - long item_size; \ - type *head, *tail, *search; \ - void (*free_func) (type *); \ - } l - -#define LIST_DECLARE_INIT(l,type,free) \ - struct { \ - long length; \ - long item_size; \ - type *head, *tail, *search; \ - void (*free_func) (type *); \ - } l = {0, sizeof (type), 0, 0, 0, (void (*) (type *)) free} - -#define linit(l,type,free) \ - { \ - memset (&(l), 0, sizeof (l)); \ - (l).item_size = sizeof (type); \ - (l).free_func = free; \ - } - -/* returns a pointer to the data of an item */ -#define ldata(i) ((void *) &((i)->data[0])) - -/* returns a pointer to the list head */ -#define lhead(l) ((l).head) - -/* returns a pointer to the list tail */ -#define ltail(l) ((l).tail) - -#define lnewsearch(l) \ - (l).search = 0; - -/* adds to the beginning of the list */ -#define lprepend(l) \ - { \ - struct list_item *__t; \ - __t = (struct list_item *) malloc ((l).item_size); \ - memset (__t, 0, (l).item_size); \ - __t->next = (l).head; \ - if (__t->next) \ - __t->next->prev = __t; \ - __t->prev = 0; \ - if (!(l).tail) \ - (l).tail = __t; \ - (l).head = __t; \ - length++; \ - } - -/* adds to the end of the list */ -#define lappend(l) \ - { \ - struct list_item *__t; \ - __t = (struct list_item *) malloc ((l).item_size); \ - memset (__t, 0, (l).item_size); \ - __t->prev = (struct list_item *) (l).tail; \ - if (__t->prev) \ - __t->prev->next = __t; \ - __t->next = 0; \ - if (!(l).head) \ - (l).head = (void *) __t; \ - (l).tail = (void *) __t; \ - (l).length++; \ - } - -/* you should free these manually */ -#define lunlink(l,e) \ - { \ - struct list_item *__t; \ - (l).search = 0; \ - __t = (void *) e; \ - if ((void *) (l).head == (void *) __t) \ - (l).head = (l).head->next; \ - if ((void *) (l).tail == (void *) __t) \ - (l).tail = (l).tail->prev; \ - if (__t->next) \ - __t->next->prev = __t->prev; \ - if (__t->prev) \ - __t->prev->next = __t->next; \ - (l).length--; \ - } - -/* deletes list entry at point e, and increments e to the following list entry */ -#define ldeleteinc(l,e) \ - { \ - struct list_item *__t; \ - (l).search = 0; \ - __t = (void *) e; \ - if ((void *) (l).head == (void *) __t) \ - (l).head = (l).head->next; \ - if ((void *) (l).tail == (void *) __t) \ - (l).tail = (l).tail->prev; \ - if (__t->next) \ - __t->next->prev = __t->prev; \ - if (__t->prev) \ - __t->prev->next = __t->next; \ - __t = __t->next; \ - if ((l).free_func) \ - (*(l).free_func) ((void *) e); \ - free (e); \ - e = (void *) __t; \ - (l).length--; \ - } - -/* deletes list entry at point e, and deccrements e to the preceding list emtry */ -#define ldeletedec(l,e) \ - { \ - struct list_item *__t; \ - (l).search = 0; \ - __t = (void *) e; \ - if ((void *) (l).head == (void *) __t) \ - (l).head = (l).head->next; \ - if ((void *) (l).tail == (void *) __t) \ - (l).tail = (l).tail->prev; \ - if (__t->next) \ - __t->next->prev = __t->prev; \ - if (__t->prev) \ - __t->prev->next = __t->next; \ - __t = __t->prev; \ - if ((l).free_func) \ - (*(l).free_func) ((void *) e); \ - free (e); \ - e = (void *) __t; \ - (l).length--; \ - } - -/* p and q must be consecutive and neither must be zero */ -#define linsert(l,p,q) \ - { \ - struct list_item *__t; \ - __t = (struct list_item *) malloc ((l).item_size); \ - memset (__t, 0, (l).item_size); \ - __t->prev = (void *) p; \ - __t->next = (void *) q; \ - q->prev = (void *) __t; \ - p->next = (void *) __t; \ - (l).length++; \ - } - -/* p and q must be consecutive and neither must be zero */ -#define ldeleteall(l) \ - { \ - (l).search = 0; \ - while ((l).head) { \ - struct list_item *__p; \ - __p = (struct list_item *) (l).head; \ - lunlink(l, __p); \ - if ((l).free_func) \ - (*(l).free_func) ((void *) __p); \ - free (__p); \ - } \ - } - -#define lloopstart(l,i) \ - for (i = (void *) (l).head; i;) { \ - struct list_item *__tl; \ - __tl = (void *) i->next; \ - -#define lloopend(l,i) \ - i = (void *) __tl; \ - } \ - -#define lloopforward(l,i,op) \ - { \ - for (i = (void *) (l).head; i;) { \ - struct list_item *__t; \ - __t = (void *) i->next; \ - op; \ - i = (void *) __t; \ - } \ - } - -#define lloopreverse(l,i,op) \ - { \ - for (i = (void *) (l).tail; i;) { \ - struct list_item *__t; \ - __t = (void *) i->prev; \ - op; \ - i = (void *) __t; \ - } \ - } - -#define lindex(l,i,n) \ - { \ - int __k; \ - for (__k = 0, i = (void *) (l).head; i && __k != n; i = i->next, __k++); \ - } - -#define lsearchforward(l,i,op) \ - { \ - int __found = 0; \ - if (!__found) \ - if ((i = (void *) (l).search)) { \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - if (!__found) \ - if ((i = (void *) (l).search->next)) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - if (!__found) \ - if ((i = (void *) (l).search->prev)) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - } \ - if (!__found) \ - for (i = (void *) (l).head; i; i = i->next) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - break; \ - } \ - } - -#define lsearchreverse(l,i,op) \ - { \ - int __found = 0; \ - if (!__found) \ - if ((i = (void *) (l).search)) { \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - if (!__found) \ - if ((i = (void *) (l).search->prev)) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - if (!__found) \ - if ((i = (void *) (l).search->next)) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - } \ - if (!__found) \ - for (i = (void *) (l).tail; i; i = i->prev) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - break; \ - } \ - } - -#define lcount(l) ((l).length) - -/* sort with comparison function see qsort(3) */ -#define larray(l,a) \ - { \ - long __i; \ - struct list_item *__p; \ - a = (void *) malloc (((l).length + 1) * sizeof (void *)); \ - for (__i = 0, __p = (void *) (l).head; __p; __p = __p->next, __i++) \ - a[__i] = (void *) __p; \ - a[__i] = 0; \ - } \ - -/* sort with comparison function see qsort(3) */ -#define llist(l,a) \ - { \ - struct list_item *__p; \ - (l).head = (void *) a[0]; \ - (l).search = 0; \ - __p = (void *) a[0]; \ - __p->prev = 0; \ - for (__j = 1; a[__j]; __j++, __p = __p->next) { \ - __p->next = (void *) a[__j]; \ - __p->next->prev = __p; \ - } \ - (l).tail = (void *) __p; \ - __p->next = 0; \ - } \ - -/* sort with comparison function see qsort(3) */ -#define lsort(l,compare) \ - { \ - void **__t; \ - long __j; \ - larray (l,__t); \ - qsort (__t, (l).length, sizeof (void *), (int (*) (const void *, const void *)) compare); \ - llist (l,__t); \ - free (__t); \ - } \ - -#endif /* GNUTLS_SRC_LIST_H */ diff --git a/src/serv.c b/src/serv.c index 5198b58c65..629c398529 100644 --- a/src/serv.c +++ b/src/serv.c @@ -28,6 +28,7 @@ #include "common.h" #include "serv-args.h" +#include "udp-serv.h" #include <stdio.h> #include <stdlib.h> #include <errno.h> @@ -38,16 +39,17 @@ #include <sys/time.h> #include <sys/select.h> #include <fcntl.h> -#include <list.h> #include <netdb.h> #include <unistd.h> #include <socket.h> /* Gnulib portability files. */ -#include "read-file.h" +#include "gl_linked_list.h" +#include "gl_xlist.h" #include "minmax.h" +#include "read-file.h" #include "sockets.h" -#include "udp-serv.h" +#include "xalloc.h" /* konqueror cannot handle sending the page in multiple * pieces. @@ -145,16 +147,21 @@ static void cmd_parser(int argc, char **argv); #define HTTP_STATE_RESPONSE 2 #define HTTP_STATE_CLOSING 3 -LIST_TYPE_DECLARE(listener_item, char *http_request; char *http_response; - int request_length; int response_length; - int response_written; int http_state; - int listen_socket; int fd; - gnutls_session_t tls_session; - int handshake_ok; - int close_ok; - time_t start; - int earlydata_eof; - ); +typedef struct { + char *http_request; + char *http_response; + int request_length; + int response_length; + int response_written; + int http_state; + int listen_socket; + int fd; + gnutls_session_t tls_session; + int handshake_ok; + int close_ok; + time_t start; + int earlydata_eof; +} listener_item; static const char *safe_strerror(int value) { @@ -164,8 +171,9 @@ static const char *safe_strerror(int value) return ret; } -static void listener_free(listener_item * j) +static void listener_free(const void *elt) { + listener_item *j = (listener_item *)elt; free(j->http_request); free(j->http_response); @@ -275,7 +283,7 @@ get_params(gnutls_session_t session, gnutls_params_type_t type, return 0; } -LIST_DECLARE_INIT(listener_list, listener_item, listener_free); +static gl_list_t listener_list; static int cert_verify_callback(gnutls_session_t session) { @@ -865,21 +873,25 @@ const char *human_addr(const struct sockaddr *sa, socklen_t salen, int wait_for_connection(void) { - listener_item *j; fd_set rd, wr; int n, sock = -1; + gl_list_iterator_t iter; + const void *elt; FD_ZERO(&rd); FD_ZERO(&wr); n = 0; - lloopstart(listener_list, j) { + iter = gl_list_iterator(listener_list); + while (gl_list_iterator_next(&iter, &elt, NULL)) { + const listener_item *j = elt; + if (j->listen_socket) { FD_SET(j->fd, &rd); n = MAX(n, j->fd); } } - lloopend(listener_list, j); + gl_list_iterator_free(&iter); /* waiting part */ n = select(n + 1, &rd, &wr, NULL, NULL); @@ -891,14 +903,17 @@ int wait_for_connection(void) } /* find which one is ready */ - lloopstart(listener_list, j) { + iter = gl_list_iterator(listener_list); + while (gl_list_iterator_next(&iter, &elt, NULL)) { + const listener_item *j = elt; + /* a new connection has arrived */ if (FD_ISSET(j->fd, &rd) && j->listen_socket) { sock = j->fd; break; } } - lloopend(listener_list, j); + gl_list_iterator_free(&iter); return sock; } @@ -997,8 +1012,8 @@ int listen_socket(const char *name, int listen_port, int socktype) } /* new list entry for the connection */ - lappend(listener_list); - j = listener_list.tail; + j = xzalloc(sizeof(*j)); + gl_list_add_last(listener_list, j); j->listen_socket = 1; j->fd = s; @@ -1151,6 +1166,10 @@ int main(int argc, char **argv) sockets_init(); + listener_list = gl_list_create_empty(GL_LINKED_LIST, + NULL, NULL, listener_free, + true); + if (nodb == 0) wrap_db_init(); @@ -1499,7 +1518,12 @@ static void tcp_server(const char *name, int port) exit(1); for (;;) { - listener_item *j; + gl_list_iterator_t iter; + gl_list_node_t node; + const void *elt; + gl_list_t accepted_list = gl_list_create_empty(GL_LINKED_LIST, + NULL, NULL, NULL, + true); fd_set rd, wr; time_t now = time(0); #ifndef _WIN32 @@ -1511,7 +1535,9 @@ static void tcp_server(const char *name, int port) n = 0; /* flag which connections we are reading or writing to within the fd sets */ - lloopstart(listener_list, j) { + iter = gl_list_iterator(listener_list); + while (gl_list_iterator_next(&iter, &elt, &node)) { + listener_item *j = (listener_item *)elt; #ifndef _WIN32 val = fcntl(j->fd, F_GETFL, 0); @@ -1541,8 +1567,9 @@ static void tcp_server(const char *name, int port) FD_SET(j->fd, &wr); n = MAX(n, j->fd); } + gl_list_node_set_value(listener_list, node, j); } - lloopend(listener_list, j); + gl_list_iterator_free(&iter); /* core operation */ tv.tv_sec = 10; @@ -1556,7 +1583,9 @@ static void tcp_server(const char *name, int port) } /* read or write to each connection as indicated by select()'s return argument */ - lloopstart(listener_list, j) { + iter = gl_list_iterator(listener_list); + while (gl_list_iterator_next(&iter, &elt, &node)) { + listener_item *j = (listener_item *)elt; /* a new connection has arrived */ if (FD_ISSET(j->fd, &rd) && j->listen_socket) { @@ -1573,23 +1602,24 @@ static void tcp_server(const char *name, int port) char timebuf[SIMPLE_CTIME_BUF_SIZE]; time_t tt = time(0); char *ctt; + listener_item *jj; /* new list entry for the connection */ - lappend(listener_list); - j = listener_list.tail; - j->http_request = + jj = xzalloc(sizeof(*jj)); + gl_list_add_last(accepted_list, jj); + jj->http_request = (char *) strdup(""); - j->http_state = HTTP_STATE_REQUEST; - j->fd = accept_fd; - j->start = tt; + jj->http_state = HTTP_STATE_REQUEST; + jj->fd = accept_fd; + jj->start = tt; - j->tls_session = initialize_session(0); - gnutls_session_set_ptr(j->tls_session, j); + jj->tls_session = initialize_session(0); + gnutls_session_set_ptr(jj->tls_session, jj); gnutls_transport_set_int - (j->tls_session, accept_fd); - set_read_funcs(j->tls_session); - j->handshake_ok = 0; - j->close_ok = 0; + (jj->tls_session, accept_fd); + set_read_funcs(jj->tls_session); + jj->handshake_ok = 0; + jj->close_ok = 0; if (verbose != 0) { ctt = simple_ctime(&tt, timebuf); @@ -1775,16 +1805,27 @@ static void tcp_server(const char *name, int port) j->http_state = HTTP_STATE_REQUEST; } } + gl_list_node_set_value(listener_list, node, j); } - lloopend(listener_list, j); + gl_list_iterator_free(&iter); /* loop through all connections, closing those that are in error */ - lloopstart(listener_list, j) { + iter = gl_list_iterator(listener_list); + while (gl_list_iterator_next(&iter, &elt, &node)) { + const listener_item *j = elt; + if (j->http_state == HTTP_STATE_CLOSING) { - ldeleteinc(listener_list, j); + gl_list_remove_node(listener_list, node); } } - lloopend(listener_list, j); + gl_list_iterator_free(&iter); + + iter = gl_list_iterator(accepted_list); + while (gl_list_iterator_next(&iter, &elt, &node)) { + gl_list_add_last(listener_list, elt); + } + gl_list_iterator_free(&iter); + gl_list_free(accepted_list); } diff --git a/src/udp-serv.c b/src/udp-serv.c index 9b71719fd2..814d698fbf 100644 --- a/src/udp-serv.c +++ b/src/udp-serv.c @@ -37,7 +37,6 @@ #include <common.h> #include "udp-serv.h" #include "serv-args.h" -#include "list.h" extern int disable_client_cert; |