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 <b...@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 _______________________________________________ dev mailing list d...@openvswitch.org https://mail.openvswitch.org/mailman/listinfo/ovs-dev