summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
authorRuss Allbery <eagle@eyrie.org>2016-04-25 20:20:15 -0700
committerRuss Allbery <eagle@eyrie.org>2016-04-25 20:20:15 -0700
commit8f46d7aa9f0e448e16964168c92c3dcb9340f229 (patch)
treef6948f0a09c49ef98b738d5594b42b799d55a0ff /util
parentade3aee596ecbde002be026d93454da6ab3e1678 (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.c39
-rw-r--r--util/network.h18
-rw-r--r--util/vector.c50
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;
}