summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaiki Ueno <ueno@gnu.org>2020-10-19 14:43:15 +0000
committerDaiki Ueno <ueno@gnu.org>2020-10-19 14:43:15 +0000
commite2bc81590564050c872820c6b14687f1d3be279a (patch)
treee486df99b1d12a5743ad3e06c71477cb378488a0
parent90f14691e1a269bf3247537e6da374f472b64d25 (diff)
parent38ef9af88193c42114548b0ad5776db0ac60e5d4 (diff)
downloadgnutls-e2bc81590564050c872820c6b14687f1d3be279a.tar.gz
Merge branch 'tmp-src-fixes' into 'master'
Add extra checks on memory allocation in src/ and examples Closes #1102 See merge request gnutls/gnutls!1344
-rw-r--r--bootstrap.conf4
-rw-r--r--doc/examples/ex-ocsp-client.c4
-rw-r--r--lib/errors.c41
-rw-r--r--lib/errors.h42
-rw-r--r--src/Makefile.am2
-rw-r--r--src/list.h446
-rw-r--r--src/serv.c162
-rw-r--r--src/udp-serv.c1
8 files changed, 158 insertions, 544 deletions
diff --git a/bootstrap.conf b/bootstrap.conf
index f8de3d4be1..8f7da96fd1 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -28,7 +28,7 @@ required_submodules="tests/suite/tls-fuzzer/python-ecdsa tests/suite/tls-fuzzer/
# Reproduce by: gnulib-tool --import --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --with-tests --avoid=alignof-tests --avoid=lock-tests --avoid=lseek-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files alloca attribute byteswap c-ctype extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash-pjw-bare havelib intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv snprintf stdint strcase strndup strtok_r strverscmp sys_socket sys_stat threadlib time_r unistd vasprintf verify vsnprintf warnings
gnulib_modules="
-alloca attribute byteswap c-ctype c-strcase extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash hash-pjw-bare havelib arpa_inet inet_ntop inet_pton intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv setsockopt snprintf stdint strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types threadlib time_r unistd valgrind-tests vasprintf verify vsnprintf warnings
+alloca attribute byteswap c-ctype c-strcase extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash hash-pjw-bare havelib arpa_inet inet_ntop inet_pton intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv setsockopt snprintf stdint stpcpy strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types threadlib time_r unistd valgrind-tests vasprintf verify vsnprintf warnings
"
unistring_modules="
@@ -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 stpcpy xalloc xlist xsize
"
# Build prerequisites
diff --git a/doc/examples/ex-ocsp-client.c b/doc/examples/ex-ocsp-client.c
index f0b56fffe2..d675e77862 100644
--- a/doc/examples/ex-ocsp-client.c
+++ b/doc/examples/ex-ocsp-client.c
@@ -91,6 +91,10 @@ int main(int argc, char *argv[])
tmp.data);
hostname = malloc(tmp.size + 1);
+ if (!hostname) {
+ fprintf(stderr, "error: cannot allocate memory\n");
+ exit(1);
+ }
memcpy(hostname, tmp.data, tmp.size);
hostname[tmp.size] = 0;
diff --git a/lib/errors.c b/lib/errors.c
index 842afe0e24..4e59d63eb2 100644
--- a/lib/errors.c
+++ b/lib/errors.c
@@ -22,7 +22,6 @@
#include "gnutls_int.h"
#include "errors.h"
-#include <libtasn1.h>
#ifdef STDC_HEADERS
#include <stdarg.h>
#endif
@@ -590,46 +589,6 @@ const char *gnutls_strerror_name(int error)
return ret;
}
-int _gnutls_asn2err(int asn_err)
-{
- switch (asn_err) {
-#ifdef ASN1_TIME_ENCODING_ERROR
- case ASN1_TIME_ENCODING_ERROR:
- return GNUTLS_E_ASN1_TIME_ERROR;
-#endif
- case ASN1_FILE_NOT_FOUND:
- return GNUTLS_E_FILE_ERROR;
- case ASN1_ELEMENT_NOT_FOUND:
- return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
- case ASN1_IDENTIFIER_NOT_FOUND:
- return GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND;
- case ASN1_DER_ERROR:
- return GNUTLS_E_ASN1_DER_ERROR;
- case ASN1_VALUE_NOT_FOUND:
- return GNUTLS_E_ASN1_VALUE_NOT_FOUND;
- case ASN1_GENERIC_ERROR:
- return GNUTLS_E_ASN1_GENERIC_ERROR;
- case ASN1_VALUE_NOT_VALID:
- return GNUTLS_E_ASN1_VALUE_NOT_VALID;
- case ASN1_TAG_ERROR:
- return GNUTLS_E_ASN1_TAG_ERROR;
- case ASN1_TAG_IMPLICIT:
- return GNUTLS_E_ASN1_TAG_IMPLICIT;
- case ASN1_ERROR_TYPE_ANY:
- return GNUTLS_E_ASN1_TYPE_ANY_ERROR;
- case ASN1_SYNTAX_ERROR:
- return GNUTLS_E_ASN1_SYNTAX_ERROR;
- case ASN1_MEM_ERROR:
- return GNUTLS_E_SHORT_MEMORY_BUFFER;
- case ASN1_MEM_ALLOC_ERROR:
- return GNUTLS_E_MEMORY_ERROR;
- case ASN1_DER_OVERFLOW:
- return GNUTLS_E_ASN1_DER_OVERFLOW;
- default:
- return GNUTLS_E_ASN1_GENERIC_ERROR;
- }
-}
-
void _gnutls_mpi_log(const char *prefix, bigint_t a)
{
size_t binlen = 0;
diff --git a/lib/errors.h b/lib/errors.h
index 976a788e7c..30ed744a49 100644
--- a/lib/errors.h
+++ b/lib/errors.h
@@ -38,7 +38,47 @@
#define gnutls_assert()
#endif
-int _gnutls_asn2err(int asn_err) __GNUTLS_CONST__;
+inline static int _gnutls_asn2err(int asn_err) __GNUTLS_CONST__;
+
+inline static int _gnutls_asn2err(int asn_err)
+{
+ switch (asn_err) {
+#ifdef ASN1_TIME_ENCODING_ERROR
+ case ASN1_TIME_ENCODING_ERROR:
+ return GNUTLS_E_ASN1_TIME_ERROR;
+#endif
+ case ASN1_FILE_NOT_FOUND:
+ return GNUTLS_E_FILE_ERROR;
+ case ASN1_ELEMENT_NOT_FOUND:
+ return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND;
+ case ASN1_IDENTIFIER_NOT_FOUND:
+ return GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND;
+ case ASN1_DER_ERROR:
+ return GNUTLS_E_ASN1_DER_ERROR;
+ case ASN1_VALUE_NOT_FOUND:
+ return GNUTLS_E_ASN1_VALUE_NOT_FOUND;
+ case ASN1_GENERIC_ERROR:
+ return GNUTLS_E_ASN1_GENERIC_ERROR;
+ case ASN1_VALUE_NOT_VALID:
+ return GNUTLS_E_ASN1_VALUE_NOT_VALID;
+ case ASN1_TAG_ERROR:
+ return GNUTLS_E_ASN1_TAG_ERROR;
+ case ASN1_TAG_IMPLICIT:
+ return GNUTLS_E_ASN1_TAG_IMPLICIT;
+ case ASN1_ERROR_TYPE_ANY:
+ return GNUTLS_E_ASN1_TYPE_ANY_ERROR;
+ case ASN1_SYNTAX_ERROR:
+ return GNUTLS_E_ASN1_SYNTAX_ERROR;
+ case ASN1_MEM_ERROR:
+ return GNUTLS_E_SHORT_MEMORY_BUFFER;
+ case ASN1_MEM_ALLOC_ERROR:
+ return GNUTLS_E_MEMORY_ERROR;
+ case ASN1_DER_OVERFLOW:
+ return GNUTLS_E_ASN1_DER_OVERFLOW;
+ default:
+ return GNUTLS_E_ASN1_GENERIC_ERROR;
+ }
+}
void _gnutls_log(int, const char *fmt, ...)
#ifdef __GNUC__
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..258af18d81 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,18 @@
#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"
+#include "xsize.h"
/* konqueror cannot handle sending the page in multiple
* pieces.
@@ -145,16 +148,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 +172,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 +284,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)
{
@@ -554,7 +563,7 @@ static char *peer_print_info(gnutls_session_t session, int *ret_length,
char *http_buffer, *desc;
gnutls_kx_algorithm_t kx_alg;
size_t len = 20 * 1024 + strlen(header);
- char *crtinfo = NULL, *crtinfo_old = NULL;
+ char *crtinfo = NULL;
gnutls_protocol_t version;
size_t ncrtinfo = 0;
@@ -592,17 +601,22 @@ static char *peer_print_info(gnutls_session_t session, int *ret_length,
&& gnutls_x509_crt_print(cert,
GNUTLS_CRT_PRINT_FULL,
&info) == 0) {
- const char *post = "</PRE><P><PRE>";
+ const char post[] = "</PRE><P><PRE>";
+ char *crtinfo_new;
+ size_t ncrtinfo_new;
- crtinfo_old = crtinfo;
- crtinfo =
- realloc(crtinfo,
- ncrtinfo + info.size +
- strlen(post) + 1);
- if (crtinfo == NULL) {
- free(crtinfo_old);
+ ncrtinfo_new = xsum3(ncrtinfo, info.size,
+ sizeof(post));
+ if (size_overflow_p(ncrtinfo_new)) {
+ free(crtinfo);
return NULL;
}
+ crtinfo_new = realloc(crtinfo, ncrtinfo_new);
+ if (crtinfo_new == NULL) {
+ free(crtinfo);
+ return NULL;
+ }
+ crtinfo = crtinfo_new;
memcpy(crtinfo + ncrtinfo, info.data,
info.size);
ncrtinfo += info.size;
@@ -865,21 +879,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 +909,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 +1018,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;
@@ -1102,7 +1123,18 @@ static void terminate(int sig) __attribute__ ((__noreturn__));
static void terminate(int sig)
{
- fprintf(stderr, "Exiting via signal %d\n", sig);
+ char buf[64] = { 0 };
+ char *p;
+
+ /* This code must be async-signal-safe. */
+ p = stpcpy(buf, "Exiting via signal ");
+
+ if (sig > 10)
+ *p++ = '0' + sig / 10;
+ *p++ = '0' + sig % 10;
+ *p++ = '\n';
+
+ write(STDERR_FILENO, buf, p - buf);
exit(1);
}
@@ -1151,6 +1183,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 +1535,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 +1552,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 +1584,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 +1600,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 +1619,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 +1822,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;