diff options
author | Russ Allbery <eagle@eyrie.org> | 2016-04-25 20:20:15 -0700 |
---|---|---|
committer | Russ Allbery <eagle@eyrie.org> | 2016-04-25 20:20:15 -0700 |
commit | 8f46d7aa9f0e448e16964168c92c3dcb9340f229 (patch) | |
tree | f6948f0a09c49ef98b738d5594b42b799d55a0ff /util | |
parent | ade3aee596ecbde002be026d93454da6ab3e1678 (diff) |
Update to rra-c-util 6.0 and C TAP Harness 4.0
Update to rra-c-util 6.0:
* Remove all remaining uses of strlcpy and strlcat.
* Fix the Perl docs/synopsis.t test to be less UNIX-specific.
* Make util/network/server-t more robust against missing IPv6.
Update to C TAP Harness 4.0:
* Use C_TAP_SOURCE and C_TAP_BUILD instead of SOURCE and BUILD.
Diffstat (limited to 'util')
-rw-r--r-- | util/network.c | 39 | ||||
-rw-r--r-- | util/network.h | 18 | ||||
-rw-r--r-- | util/vector.c | 50 |
3 files changed, 58 insertions, 49 deletions
diff --git a/util/network.c b/util/network.c index 07aa067..29098ff 100644 --- a/util/network.c +++ b/util/network.c @@ -20,7 +20,7 @@ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. * * Written by Russ Allbery <eagle@eyrie.org> - * Copyright 2014, 2015 Russ Allbery <eagle@eyrie.org> + * Copyright 2014, 2015, 2016 Russ Allbery <eagle@eyrie.org> * Copyright 2009, 2011, 2012, 2013, 2014 * The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2004, 2005, 2006, 2007, 2008 @@ -73,21 +73,6 @@ # define sin6_set_length(s) /* empty */ #endif -/* If SO_REUSEADDR isn't available, make calls to set_reuseaddr go away. */ -#ifndef SO_REUSEADDR -# define network_set_reuseaddr(fd) /* empty */ -#endif - -/* If IPV6_V6ONLY isn't available, make calls to set_v6only go away. */ -#ifndef IPV6_V6ONLY -# define network_set_v6only(fd) /* empty */ -#endif - -/* If IP_FREEBIND isn't available, make calls to set_freebind go away. */ -#ifndef IP_FREEBIND -# define network_set_freebind(fd) /* empty */ -#endif - /* * Windows requires a different function when sending to sockets, but can't * return short writes on blocking sockets. @@ -98,53 +83,53 @@ # define socket_xwrite(fd, b, s) xwrite((fd), (b), (s)) #endif + /* * Set SO_REUSEADDR on a socket if possible (so that something new can listen * on the same port immediately if the daemon dies unexpectedly). */ -#ifdef SO_REUSEADDR -static void +void network_set_reuseaddr(socket_type fd) { +#ifdef SO_REUSEADDR int flag = 1; - const void *flagaddr = &flag; - if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, flagaddr, sizeof(flag)) < 0) + if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag)) < 0) syswarn("cannot mark bind address reusable"); -} #endif +} /* * Set IPV6_V6ONLY on a socket if possible, since the IPv6 behavior is more * consistent and easier to understand. */ -#ifdef IPV6_V6ONLY -static void +void network_set_v6only(socket_type fd) { +#ifdef IPV6_V6ONLY int flag = 1; if (setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag)) < 0) syswarn("cannot set IPv6 socket to v6only"); -} #endif +} /* * Set IP_FREEBIND on a socket if possible, which allows binding servers to * IPv6 addresses that may not have been set up yet. */ -#ifdef IP_FREEBIND -static void +void network_set_freebind(socket_type fd) { +#ifdef IP_FREEBIND int flag = 1; if (setsockopt(fd, IPPROTO_IP, IP_FREEBIND, &flag, sizeof(flag)) < 0) syswarn("cannot set IPv6 socket to free binding"); -} #endif +} /* diff --git a/util/network.h b/util/network.h index 6532018..b981ea5 100644 --- a/util/network.h +++ b/util/network.h @@ -5,7 +5,7 @@ * which can be found at <http://www.eyrie.org/~eagle/software/rra-c-util/>. * * Written by Russ Allbery <eagle@eyrie.org> - * Copyright 2014 Russ Allbery <eagle@eyrie.org> + * Copyright 2014, 2016 Russ Allbery <eagle@eyrie.org> * Copyright 2009, 2010, 2011, 2012, 2013 * The Board of Trustees of the Leland Stanford Junior University * Copyright (c) 2004, 2005, 2006, 2007, 2008, 2010 @@ -127,6 +127,22 @@ socket_type network_connect_host(const char *host, unsigned short port, socket_type network_client_create(int domain, int type, const char *source); /* + * Set various socket flags if possible, but do nothing, silently, if that + * option is not supported. If the option is supported but setting the flag + * fails, log a warning with syswarn. + * + * network_set_freebind sets IP_FREEBIND, which allows binding IPv6 addresses + * that may not have been set up yet. network_set_reuseaddr sets SO_REUSEADDR + * so that something new can listen on the same port immediately if the daemon + * dies unexpectedly. network_set_v6only sets IP_V6ONLY, which avoids binding + * to the backward-compatibility IPv4 address when binding an IPv6 socket + * (generally preferred since the behavior is more predictable). + */ +void network_set_freebind(socket_type fd); +void network_set_reuseaddr(socket_type fd); +void network_set_v6only(socket_type fd); + +/* * Read or write the specified number of bytes to the network, enforcing a * timeout. Both return true on success and false on failure; on failure, the * socket errno is set. diff --git a/util/vector.c b/util/vector.c index 1c1677f..ab48539 100644 --- a/util/vector.c +++ b/util/vector.c @@ -113,24 +113,20 @@ cvector_resize(struct cvector *vector, size_t size) void vector_add(struct vector *vector, const char *string) { - size_t next = vector->count; - assert(vector != NULL); if (vector->count == vector->allocated) vector_resize(vector, vector->allocated + 1); - vector->strings[next] = xstrdup(string); + vector->strings[vector->count] = xstrdup(string); vector->count++; } void cvector_add(struct cvector *vector, const char *string) { - size_t next = vector->count; - assert(vector != NULL); if (vector->count == vector->allocated) cvector_resize(vector, vector->allocated + 1); - vector->strings[next] = string; + vector->strings[vector->count] = string; vector->count++; } @@ -144,12 +140,10 @@ cvector_add(struct cvector *vector, const char *string) void vector_addn(struct vector *vector, const char *string, size_t length) { - size_t next = vector->count; - assert(vector != NULL); if (vector->count == vector->allocated) vector_resize(vector, vector->allocated + 1); - vector->strings[next] = xstrndup(string, length); + vector->strings[vector->count] = xstrndup(string, length); vector->count++; } @@ -463,7 +457,7 @@ char * vector_join(const struct vector *vector, const char *separator) { char *string; - size_t i, size, seplen; + size_t i, length, offset, size, seplen; /* If the vector is empty, this is trivial. */ assert(vector != NULL); @@ -482,13 +476,20 @@ vector_join(const struct vector *vector, const char *separator) assert(SIZE_MAX - size >= (vector->count - 1) * seplen + 1); size += (vector->count - 1) * seplen + 1; - /* Allocate the memory and build up the string using strlcat. */ + /* Allocate the memory and build up the string. */ string = xmalloc(size); - strlcpy(string, vector->strings[0], size); - for (i = 1; i < vector->count; i++) { - strlcat(string, separator, size); - strlcat(string, vector->strings[i], size); + offset = 0; + for (i = 0; i < vector->count; i++) { + if (i != 0) { + memcpy(string + offset, separator, seplen); + offset += seplen; + } + length = strlen(vector->strings[i]); + memcpy(string + offset, vector->strings[i], length); + offset += length; + assert(offset < size); } + string[offset] = '\0'; return string; } @@ -496,7 +497,7 @@ char * cvector_join(const struct cvector *vector, const char *separator) { char *string; - size_t i, size, seplen; + size_t i, length, offset, size, seplen; /* If the vector is empty, this is trivial. */ assert(vector != NULL); @@ -515,13 +516,20 @@ cvector_join(const struct cvector *vector, const char *separator) assert(SIZE_MAX - size >= (vector->count - 1) * seplen + 1); size += (vector->count - 1) * seplen + 1; - /* Allocate the memory and build up the string using strlcat. */ + /* Allocate the memory and build up the string. */ string = xmalloc(size); - strlcpy(string, vector->strings[0], size); - for (i = 1; i < vector->count; i++) { - strlcat(string, separator, size); - strlcat(string, vector->strings[i], size); + offset = 0; + for (i = 0; i < vector->count; i++) { + if (i != 0) { + memcpy(string + offset, separator, seplen); + offset += seplen; + } + length = strlen(vector->strings[i]); + memcpy(string + offset, vector->strings[i], length); + offset += length; + assert(offset < size); } + string[offset] = '\0'; return string; } |