From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from imap.gmail.com [173.194.76.109] by localhost with POP3 (fetchmail-6.3.26) for (single-drop); Tue, 21 May 2024 06:48:39 +0200 (CEST) Received: by 2002:a05:6a10:9148:b0:55f:c3c0:ed08 with SMTP id n8csp830029pxb; Mon, 20 May 2024 21:48:17 -0700 (PDT) X-Forwarded-Encrypted: i=2; AJvYcCUEAF38/Cp5hT735yvAqnX+bv43bj+q4CO6iGK+Y3l8YqWQBsUlBWkRbM0QZ2wNrtng+SOVMUuK4lfu9XJsYyglmLqQj6baGsU= X-Google-Smtp-Source: AGHT+IGcWDbAHJaclJzhXsxzqT4+aBhnGowKB6jEVXI5I6DQgRoWUcTB41InpLcogJ9NhLBb7sN4 X-Received: by 2002:a05:622a:1808:b0:43a:ef50:e6f1 with SMTP id d75a77b69052e-43dfdaf2fbemr376198981cf.33.1716266897207; Mon, 20 May 2024 21:48:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1716266897; cv=none; d=google.com; s=arc-20160816; b=sY0We9RLVlPuKyfhMsfTRwtfkWqn9DNQkzNWh3Qg8j0TJ9ydRs4qe+mkhboEmxumNF 9Vv4bq/xV5c5ZevFABT9w03UEbUVnrNkUN2PFkELNu51KldEAyi3X3IdaaicEjD6I4jc 64U0sRL8UHOn/mo0HbPvWoSnObFDaPpLZ+UBACUzO0g4OL2E1ztkj6kLzHtkvpBKRKni F6Wr4etiXnXCFbEI8sjwecXon3Ru/y1wLqRM8se4Rh5PtknMacCfsjWQbDrncr5oPKgc +qeunJjY8Z0fhJohZHjg0QtzHFW3Ak/dS3KA8KNyrwlVOUMk9QcDdo2OPqwc9SCN4vC2 3quA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:delivered-to; bh=env0MJeLzVJLT8ScpSy+HiIKTP+lB/oaRwdsHZmgL70=; fh=OvZxoe0l5OQEr5hiks2YsWDyoZfSCuw/Wl/AnSjLRjU=; b=z/JphRvouylyOrbU+Vo2XWG6GvxvnzkPhTakMX31B5HlApoSY0I19Ly0WPKdMwOjmH 3pvjboWBlN+gX+e08miRjboWau8sAU1BK5n8JysV0XVkz2ZcSR+Dm4TdMUSkKKUY1Zz0 kSYjVsf8RK66gETQ7zSHHHqZljNiil24xv7TcvWyggJyzsF4r2cbxKPzftyklSA+Kkh6 wzYDdZjNBA9fboOMlpFW65uWuVhI0ona5LlPSYN+7H5b18oSh6ZpD0mZ3xyVIiKRbGxk Z3+bp+3zZXlEkm1ni2gPBoPnA7vRH+mHtFoCTQ1RYVMF7pTzRtocuZRhRzOZjSo0vYLN /PCw==; dara=google.com ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of dgibson@gandalf.ozlabs.org designates 150.107.74.76 as permitted sender) smtp.mailfrom=dgibson@gandalf.ozlabs.org Return-Path: Received: from us-smtp-inbound-delivery-1.mimecast.com (us-smtp-delivery-1.mimecast.com. [170.10.128.131]) by mx.google.com with ESMTPS id d75a77b69052e-43e3d38e185si22230711cf.657.2024.05.20.21.48.16 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 20 May 2024 21:48:16 -0700 (PDT) Received-SPF: pass (google.com: domain of dgibson@gandalf.ozlabs.org designates 150.107.74.76 as permitted sender) client-ip=150.107.74.76; Authentication-Results: mx.google.com; spf=pass (google.com: domain of dgibson@gandalf.ozlabs.org designates 150.107.74.76 as permitted sender) smtp.mailfrom=dgibson@gandalf.ozlabs.org Received: from mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-641-_cjOew7OMXqjfgvQONbbzA-1; Tue, 21 May 2024 00:48:14 -0400 X-MC-Unique: _cjOew7OMXqjfgvQONbbzA-1 Received: from mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.40]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 72B301955E80 for ; Tue, 21 May 2024 04:48:13 +0000 (UTC) Received: by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) id 27DD91955D7D; Tue, 21 May 2024 04:48:13 +0000 (UTC) Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.33]) by mx-prod-int-04.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 25A561955D7C for ; Tue, 21 May 2024 04:48:13 +0000 (UTC) Received: from us-smtp-inbound-delivery-1.mimecast.com (us-smtp-delivery-1.mimecast.com [205.139.110.120]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id D483219541A7 for ; Tue, 21 May 2024 04:48:12 +0000 (UTC) Received: from mail.ozlabs.org (gandalf.ozlabs.org [150.107.74.76]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-586-tjOQqFs6Nl6sG1yg8vUCSw-1; Tue, 21 May 2024 00:48:09 -0400 X-MC-Unique: tjOQqFs6Nl6sG1yg8vUCSw-1 Received: by gandalf.ozlabs.org (Postfix, from userid 1007) id 4Vk24N4vcwz4wyQ; Tue, 21 May 2024 14:48:04 +1000 (AEST) From: David Gibson To: Stefano Brivio , passt-dev@passt.top Cc: David Gibson Subject: [PATCH v3] util, tcp: Add helper to display socket addresses Date: Tue, 21 May 2024 14:48:03 +1000 Message-ID: <20240521044803.782548-1-david@gibson.dropbear.id.au> MIME-Version: 1.0 X-Mimecast-Impersonation-Protect: Policy=CLT - Impersonation Protection Definition;Similar Internal Domain=false;Similar Monitored External Domain=false;Custom External Domain=false;Mimecast External Domain=false;Newly Observed Domain=false;Internal User Name=false;Custom Display Name List=false;Reply-to Address Mismatch=false;Targeted Threat Dictionary=false;Mimecast Threat Dictionary=false;Custom Threat Dictionary=false X-Scanned-By: MIMEDefang 3.0 on 10.30.177.40 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: gibson.dropbear.id.au Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="US-ASCII"; x-default=true List-Id: When reporting errors, we sometimes want to show a relevant socket address. Doing so by extracting the various relevant fields can be pretty awkward, so introduce a sockaddr_ntop() helper to make it simpler. For now we just have one user in tcp.c, but I have further upcoming patches which can make use of it. Signed-off-by: David Gibson --- tcp.c | 23 +++++++++-------------- util.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ util.h | 14 ++++++++++++++ 3 files changed, 79 insertions(+), 14 deletions(-) Changes since v2: * Removed use of iprintf() helper function, use some macros instead. * Use sizeof("literal") approach to simplify some things. =20 Changes since v1: * More careful and documented reasoning about the size of the strings needed for output. * Some more complex logic to calling inet_ntop() into a temporary buffer then copying it diff --git a/tcp.c b/tcp.c index 21d0af06..efbbc1c0 100644 --- a/tcp.c +++ b/tcp.c @@ -2758,6 +2758,7 @@ static void tcp_tap_conn_from_sock(struct ctx *c, in_= port_t dstport, void tcp_listen_handler(struct ctx *c, union epoll_ref ref, =09=09=09const struct timespec *now) { +=09char sastr[SOCKADDR_STRLEN]; =09union sockaddr_inany sa; =09socklen_t sl =3D sizeof(sa); =09union flow *flow; @@ -2776,25 +2777,15 @@ void tcp_listen_handler(struct ctx *c, union epoll_= ref ref, =20 =09=09if (IN4_IS_ADDR_UNSPECIFIED(addr) || =09=09 IN4_IS_ADDR_BROADCAST(addr) || -=09=09 IN4_IS_ADDR_MULTICAST(addr) || port =3D=3D 0) { -=09=09=09char str[INET_ADDRSTRLEN]; - -=09=09=09err("Invalid endpoint from TCP accept(): %s:%hu", -=09=09=09 inet_ntop(AF_INET, addr, str, sizeof(str)), port); -=09=09=09goto cancel; -=09=09} +=09=09 IN4_IS_ADDR_MULTICAST(addr) || port =3D=3D 0) +=09=09=09goto bad_endpoint; =09} else if (sa.sa_family =3D=3D AF_INET6) { =09=09const struct in6_addr *addr =3D &sa.sa6.sin6_addr; =09=09in_port_t port =3D sa.sa6.sin6_port; =20 =09=09if (IN6_IS_ADDR_UNSPECIFIED(addr) || -=09=09 IN6_IS_ADDR_MULTICAST(addr) || port =3D=3D 0) { -=09=09=09char str[INET6_ADDRSTRLEN]; - -=09=09=09err("Invalid endpoint from TCP accept(): %s:%hu", -=09=09=09 inet_ntop(AF_INET6, addr, str, sizeof(str)), port); -=09=09=09goto cancel; -=09=09} +=09=09 IN6_IS_ADDR_MULTICAST(addr) || port =3D=3D 0) +=09=09=09goto bad_endpoint; =09} =20 =09if (tcp_splice_conn_from_sock(c, ref.tcp_listen.pif, @@ -2804,6 +2795,10 @@ void tcp_listen_handler(struct ctx *c, union epoll_r= ef ref, =09tcp_tap_conn_from_sock(c, ref.tcp_listen.port, flow, s, &sa, now); =09return; =20 +bad_endpoint: +=09err("Invalid endpoint from TCP accept(): %s", +=09 sockaddr_ntop(&sa, sastr, sizeof(sastr))); + cancel: =09flow_alloc_cancel(flow); } diff --git a/util.c b/util.c index 849fa7f6..d66d366a 100644 --- a/util.c +++ b/util.c @@ -553,3 +553,59 @@ int write_remainder(int fd, const struct iovec *iov, i= nt iovcnt, size_t skip) =20 =09return 0; } + +/** sockaddr_ntop() - Convert a socket address to text format + * @sa:=09=09Socket address + * @dst:=09output buffer, minimum SOCKADDR_STRLEN bytes + * @size:=09size of buffer at @dst + * + * Return: On success, a non-null pointer to @dst, NULL on failure + */ +const char *sockaddr_ntop(const void *sa, char *dst, socklen_t size) +{ +=09sa_family_t family =3D ((const struct sockaddr *)sa)->sa_family; +=09socklen_t off =3D 0; + +#define IPRINTF(...)=09=09=09=09=09=09=09\ +=09do {=09=09=09=09=09=09=09=09\ +=09=09off +=3D snprintf(dst + off, size - off, __VA_ARGS__);=09\ +=09=09if (off >=3D size)=09=09=09=09=09\ +=09=09=09return NULL;=09=09=09=09=09\ +=09} while (0) + +#define INTOP(af, addr)=09=09=09=09=09=09=09\ +=09do {=09=09=09=09=09=09=09=09\ +=09=09if (!inet_ntop((af), (addr), dst + off, size - off))=09\ +=09=09=09return NULL;=09=09=09=09=09\ +=09=09off +=3D strlen(dst + off);=09=09=09=09\ +=09} while (0) + +=09switch (family) { +=09case AF_INET: { +=09=09const struct sockaddr_in *sa4 =3D sa; + +=09=09INTOP(AF_INET, &sa4->sin_addr); +=09=09IPRINTF(":%hu", ntohs(sa4->sin_port)); +=09=09break; +=09} + +=09case AF_INET6: { +=09=09const struct sockaddr_in6 *sa6 =3D sa; + +=09=09IPRINTF("["); +=09=09INTOP(AF_INET6, &sa6->sin6_addr); +=09=09IPRINTF("]:%hu", ntohs(sa6->sin6_port)); +=09=09break; +=09} + +=09=09/* FIXME: Implement AF_UNIX */ +=09default: +=09=09errno =3D EAFNOSUPPORT; +=09=09return NULL; +=09} + +#undef IPRINTF +#undef INTOP +=09 +=09return dst; +} diff --git a/util.h b/util.h index 264423bb..c8a357e3 100644 --- a/util.h +++ b/util.h @@ -180,6 +180,20 @@ static inline const char *af_name(sa_family_t af) =09} } =20 +#define UINT16_STRLEN=09=09(sizeof("65535")) + +/* inet address (- '\0') + port (u16) (- '\0') + ':' + '\0' */ +#define SOCKADDR_INET_STRLEN=09=09=09=09=09\ +=09(INET_ADDRSTRLEN-1 + UINT16_STRLEN-1 + sizeof(":")) + +/* inet6 address (- '\0') + port (u16) (- '\0') + '[' + ']' + ':' + '\0' *= / +#define SOCKADDR_INET6_STRLEN=09=09=09=09\ +=09(INET6_ADDRSTRLEN-1 + UINT16_STRLEN-1 + sizeof("[]:")) + +#define SOCKADDR_STRLEN=09=09MAX(SOCKADDR_INET_STRLEN, SOCKADDR_INET6_STRL= EN) + +const char *sockaddr_ntop(const void *sa, char *dst, socklen_t size); + /** * mod_sub() - Modular arithmetic subtraction * @a:=09=09Minued, unsigned value < @m --=20 2.45.1