[ovs-dev] [PATCH v2 2/3] socket-util: Change ss_format_address() to take a dynamic string.
Ben Pfaff
blp at ovn.org
Fri Jul 14 21:33:45 UTC 2017
It's occasionally convenient to format into a fixed-size buffer, but
as the use cases, and the text to be formatted, get more sophisticated,
it becomes easier to deal with "struct ds *" than a buffer pointer and
length pair. An upcoming commit will make ss_format_address() do more
work, and I think that this is the point at which it becomes easier to
take a dynamic string. This commit makes the parameter type change
without yet changing what is formatted.
Signed-off-by: Ben Pfaff <blp at ovn.org>
---
lib/socket-util.c | 36 ++++++++++++++++--------------------
lib/socket-util.h | 6 +++---
lib/stream-ssl.c | 25 +++++++++++++------------
lib/stream-tcp.c | 30 +++++++++++++-----------------
4 files changed, 45 insertions(+), 52 deletions(-)
diff --git a/lib/socket-util.c b/lib/socket-util.c
index 04401d49de27..82975aa62981 100644
--- a/lib/socket-util.c
+++ b/lib/socket-util.c
@@ -808,11 +808,8 @@ describe_sockaddr(struct ds *string, int fd,
if (!getaddr(fd, (struct sockaddr *) &ss, &len)) {
if (ss.ss_family == AF_INET || ss.ss_family == AF_INET6) {
- char addrbuf[SS_NTOP_BUFSIZE];
-
- ds_put_format(string, "%s:%"PRIu16,
- ss_format_address(&ss, addrbuf, sizeof addrbuf),
- ss_get_port(&ss));
+ ss_format_address(&ss, string);
+ ds_put_format(string, ":%"PRIu16, ss_get_port(&ss));
#ifndef _WIN32
} else if (ss.ss_family == AF_UNIX) {
struct sockaddr_un sun;
@@ -961,33 +958,32 @@ ss_get_port(const struct sockaddr_storage *ss)
}
}
-/* Formats the IPv4 or IPv6 address in 'ss' into the 'bufsize' bytes in 'buf'.
- * If 'ss' is an IPv6 address, puts square brackets around the address.
- * 'bufsize' should be at least SS_NTOP_BUFSIZE.
- *
- * Returns 'buf'. */
-char *
-ss_format_address(const struct sockaddr_storage *ss,
- char *buf, size_t bufsize)
+
+/* Formats the IPv4 or IPv6 address in 'ss' into 's'. If 'ss' is an IPv6
+ * address, puts square brackets around the address. 'bufsize' should be at
+ * least SS_NTOP_BUFSIZE. */
+void
+ss_format_address(const struct sockaddr_storage *ss, struct ds *s)
{
- ovs_assert(bufsize >= SS_NTOP_BUFSIZE);
if (ss->ss_family == AF_INET) {
const struct sockaddr_in *sin
= ALIGNED_CAST(const struct sockaddr_in *, ss);
- snprintf(buf, bufsize, IP_FMT, IP_ARGS(sin->sin_addr.s_addr));
+ ds_put_format(s, IP_FMT, IP_ARGS(sin->sin_addr.s_addr));
} else if (ss->ss_family == AF_INET6) {
const struct sockaddr_in6 *sin6
= ALIGNED_CAST(const struct sockaddr_in6 *, ss);
- buf[0] = '[';
- inet_ntop(AF_INET6, sin6->sin6_addr.s6_addr, buf + 1, bufsize - 1);
- strcpy(strchr(buf, '\0'), "]");
+ ds_put_char(s, '[');
+ ds_reserve(s, s->length + INET6_ADDRSTRLEN);
+ char *tail = &s->string[s->length];
+ inet_ntop(AF_INET6, sin6->sin6_addr.s6_addr, tail, INET6_ADDRSTRLEN);
+ s->length += strlen(tail);
+
+ ds_put_char(s, ']');
} else {
OVS_NOT_REACHED();
}
-
- return buf;
}
size_t
diff --git a/lib/socket-util.h b/lib/socket-util.h
index ef316cb8cc72..1782745fa2c0 100644
--- a/lib/socket-util.h
+++ b/lib/socket-util.h
@@ -28,6 +28,8 @@
#include <netinet/in_systm.h>
#include <netinet/ip.h>
+struct ds;
+
int set_nonblocking(int fd);
void xset_nonblocking(int fd);
void setsockopt_tcp_nodelay(int fd);
@@ -71,9 +73,7 @@ char *describe_fd(int fd);
/* Functions for working with sockaddr_storage that might contain an IPv4 or
* IPv6 address. */
uint16_t ss_get_port(const struct sockaddr_storage *);
-#define SS_NTOP_BUFSIZE (1 + INET6_ADDRSTRLEN + 1)
-char *ss_format_address(const struct sockaddr_storage *,
- char *buf, size_t bufsize);
+void ss_format_address(const struct sockaddr_storage *, struct ds *);
size_t ss_length(const struct sockaddr_storage *);
const char *sock_strerror(int error);
diff --git a/lib/stream-ssl.c b/lib/stream-ssl.c
index 6dc6f25fddf9..a198d6783dbb 100644
--- a/lib/stream-ssl.c
+++ b/lib/stream-ssl.c
@@ -825,8 +825,6 @@ static int
pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
uint8_t dscp)
{
- char bound_name[SS_NTOP_BUFSIZE + 16];
- char addrbuf[SS_NTOP_BUFSIZE];
struct sockaddr_storage ss;
struct pssl_pstream *pssl;
uint16_t port;
@@ -844,14 +842,18 @@ pssl_open(const char *name OVS_UNUSED, char *suffix, struct pstream **pstreamp,
}
port = ss_get_port(&ss);
- snprintf(bound_name, sizeof bound_name, "pssl:%"PRIu16":%s",
- port, ss_format_address(&ss, addrbuf, sizeof addrbuf));
+
+ struct ds bound_name = DS_EMPTY_INITIALIZER;
+ ds_put_format(&bound_name, "pssl:%"PRIu16":", port);
+ ss_format_address(&ss, &bound_name);
pssl = xmalloc(sizeof *pssl);
- pstream_init(&pssl->pstream, &pssl_pstream_class, xstrdup(bound_name));
+ pstream_init(&pssl->pstream, &pssl_pstream_class,
+ ds_steal_cstr(&bound_name));
pstream_set_bound_port(&pssl->pstream, htons(port));
pssl->fd = fd;
*pstreamp = &pssl->pstream;
+
return 0;
}
@@ -867,8 +869,6 @@ static int
pssl_accept(struct pstream *pstream, struct stream **new_streamp)
{
struct pssl_pstream *pssl = pssl_pstream_cast(pstream);
- char name[SS_NTOP_BUFSIZE + 16];
- char addrbuf[SS_NTOP_BUFSIZE];
struct sockaddr_storage ss;
socklen_t ss_len = sizeof ss;
int new_fd;
@@ -894,11 +894,12 @@ pssl_accept(struct pstream *pstream, struct stream **new_streamp)
return error;
}
- snprintf(name, sizeof name, "ssl:%s:%"PRIu16,
- ss_format_address(&ss, addrbuf, sizeof addrbuf),
- ss_get_port(&ss));
- return new_ssl_stream(xstrdup(name), new_fd, SERVER, STATE_SSL_CONNECTING,
- new_streamp);
+ struct ds name = DS_EMPTY_INITIALIZER;
+ ds_put_cstr(&name, "ssl:");
+ ss_format_address(&ss, &name);
+ ds_put_format(&name, ":%"PRIu16, ss_get_port(&ss));
+ return new_ssl_stream(ds_steal_cstr(&name), new_fd, SERVER,
+ STATE_SSL_CONNECTING, new_streamp);
}
static void
diff --git a/lib/stream-tcp.c b/lib/stream-tcp.c
index da88cbafaf9e..4fae731d9b9e 100644
--- a/lib/stream-tcp.c
+++ b/lib/stream-tcp.c
@@ -84,13 +84,9 @@ static int
new_pstream(char *suffix, const char *name, struct pstream **pstreamp,
int dscp, char *unlink_path, bool kernel_print_port)
{
- char bound_name[SS_NTOP_BUFSIZE + 16];
- char addrbuf[SS_NTOP_BUFSIZE];
struct sockaddr_storage ss;
int error;
- uint16_t port;
int fd;
- char *conn_name = CONST_CAST(char *, name);
fd = inet_open_passive(SOCK_STREAM, suffix, -1, &ss, dscp,
kernel_print_port);
@@ -98,17 +94,18 @@ new_pstream(char *suffix, const char *name, struct pstream **pstreamp,
return -fd;
}
- port = ss_get_port(&ss);
- if (!conn_name) {
- snprintf(bound_name, sizeof bound_name, "ptcp:%"PRIu16":%s",
- port, ss_format_address(&ss, addrbuf, sizeof addrbuf));
- conn_name = bound_name;
+ struct ds bound_name = DS_EMPTY_INITIALIZER;
+ if (!name) {
+ ds_put_format(&bound_name, "ptcp:%"PRIu16":", ss_get_port(&ss));
+ ss_format_address(&ss, &bound_name);
+ } else {
+ ds_put_cstr(&bound_name, name);
}
- error = new_fd_pstream(xstrdup(conn_name), fd,
+ error = new_fd_pstream(ds_steal_cstr(&bound_name), fd,
ptcp_accept, unlink_path, pstreamp);
if (!error) {
- pstream_set_bound_port(*pstreamp, htons(port));
+ pstream_set_bound_port(*pstreamp, htons(ss_get_port(&ss)));
}
return error;
}
@@ -124,13 +121,12 @@ static int
ptcp_accept(int fd, const struct sockaddr_storage *ss,
size_t ss_len OVS_UNUSED, struct stream **streamp)
{
- char name[SS_NTOP_BUFSIZE + 16];
- char addrbuf[SS_NTOP_BUFSIZE];
+ struct ds name = DS_EMPTY_INITIALIZER;
+ ds_put_cstr(&name, "tcp:");
+ ss_format_address(ss, &name);
+ ds_put_format(&name, ":%"PRIu16, ss_get_port(ss));
- snprintf(name, sizeof name, "tcp:%s:%"PRIu16,
- ss_format_address(ss, addrbuf, sizeof addrbuf),
- ss_get_port(ss));
- return new_tcp_stream(xstrdup(name), fd, 0, streamp);
+ return new_tcp_stream(ds_steal_cstr(&name), fd, 0, streamp);
}
const struct pstream_class ptcp_pstream_class = {
--
2.10.2
More information about the dev
mailing list