From patchwork Fri Jul 14 21:33:45 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Pfaff X-Patchwork-Id: 788808 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3x8QvQ3jPsz9s7F for ; Sat, 15 Jul 2017 07:34:58 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id D81F0E3F; Fri, 14 Jul 2017 21:34:02 +0000 (UTC) X-Original-To: dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 4D6AFE28 for ; Fri, 14 Jul 2017 21:34:00 +0000 (UTC) X-Greylist: domain auto-whitelisted by SQLgrey-1.7.6 Received: from relay3-d.mail.gandi.net (relay3-d.mail.gandi.net [217.70.183.195]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 907003E7 for ; Fri, 14 Jul 2017 21:33:59 +0000 (UTC) Received: from mfilter11-d.gandi.net (mfilter11-d.gandi.net [217.70.178.131]) by relay3-d.mail.gandi.net (Postfix) with ESMTP id 60BB2A80C1; Fri, 14 Jul 2017 23:33:58 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at mfilter11-d.gandi.net Received: from relay3-d.mail.gandi.net ([IPv6:::ffff:217.70.183.195]) by mfilter11-d.gandi.net (mfilter11-d.gandi.net [::ffff:10.0.15.180]) (amavisd-new, port 10024) with ESMTP id WInDVRejSQRe; Fri, 14 Jul 2017 23:33:56 +0200 (CEST) X-Originating-IP: 208.91.2.3 Received: from sigabrt.benpfaff.org (unknown [208.91.2.3]) (Authenticated sender: blp@ovn.org) by relay3-d.mail.gandi.net (Postfix) with ESMTPSA id 93AD3A80C6; Fri, 14 Jul 2017 23:33:55 +0200 (CEST) From: Ben Pfaff To: dev@openvswitch.org Date: Fri, 14 Jul 2017 14:33:45 -0700 Message-Id: <20170714213346.21944-3-blp@ovn.org> X-Mailer: git-send-email 2.10.2 In-Reply-To: <20170714213346.21944-1-blp@ovn.org> References: <20170714213346.21944-1-blp@ovn.org> X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_LOW autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Cc: Ben Pfaff Subject: [ovs-dev] [PATCH v2 2/3] socket-util: Change ss_format_address() to take a dynamic string. X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org 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 --- 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 #include +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 = {