From 9d967b01c870716a2aaca116582604cc2295b2b3 Mon Sep 17 00:00:00 2001 From: Joakim Plate Date: Wed, 21 Jan 2026 21:32:39 +0100 Subject: [PATCH] Expose sockaddr to string formatter (#12351) --- esphome/components/socket/socket.cpp | 14 +++++++------- esphome/components/socket/socket.h | 3 +++ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/esphome/components/socket/socket.cpp b/esphome/components/socket/socket.cpp index bb94ecb675..fd8725b363 100644 --- a/esphome/components/socket/socket.cpp +++ b/esphome/components/socket/socket.cpp @@ -46,15 +46,15 @@ static inline const char *esphome_inet_ntop6(const void *addr, char *buf, size_t #endif // Format sockaddr into caller-provided buffer, returns length written (excluding null) -static size_t format_sockaddr_to(const struct sockaddr_storage &storage, std::span buf) { - if (storage.ss_family == AF_INET) { - const auto *addr = reinterpret_cast(&storage); +size_t format_sockaddr_to(const struct sockaddr *addr_ptr, socklen_t len, std::span buf) { + if (addr_ptr->sa_family == AF_INET && len >= sizeof(const struct sockaddr_in)) { + const auto *addr = reinterpret_cast(addr_ptr); if (esphome_inet_ntop4(&addr->sin_addr, buf.data(), buf.size()) != nullptr) return strlen(buf.data()); } #if USE_NETWORK_IPV6 - else if (storage.ss_family == AF_INET6) { - const auto *addr = reinterpret_cast(&storage); + else if (addr_ptr->sa_family == AF_INET6 && len >= sizeof(sockaddr_in6)) { + const auto *addr = reinterpret_cast(addr_ptr); #ifndef USE_SOCKET_IMPL_LWIP_TCP // Format IPv4-mapped IPv6 addresses as regular IPv4 (not supported on ESP8266 raw TCP) if (addr->sin6_addr.un.u32_addr[0] == 0 && addr->sin6_addr.un.u32_addr[1] == 0 && @@ -78,7 +78,7 @@ size_t Socket::getpeername_to(std::span buf) { buf[0] = '\0'; return 0; } - return format_sockaddr_to(storage, buf); + return format_sockaddr_to(reinterpret_cast(&storage), len, buf); } size_t Socket::getsockname_to(std::span buf) { @@ -88,7 +88,7 @@ size_t Socket::getsockname_to(std::span buf) { buf[0] = '\0'; return 0; } - return format_sockaddr_to(storage, buf); + return format_sockaddr_to(reinterpret_cast(&storage), len, buf); } std::unique_ptr socket_ip(int type, int protocol) { diff --git a/esphome/components/socket/socket.h b/esphome/components/socket/socket.h index d74804fdb0..e8b0948acd 100644 --- a/esphome/components/socket/socket.h +++ b/esphome/components/socket/socket.h @@ -102,6 +102,9 @@ inline socklen_t set_sockaddr(struct sockaddr *addr, socklen_t addrlen, const st /// Set a sockaddr to the any address and specified port for the IP version used by socket_ip(). socklen_t set_sockaddr_any(struct sockaddr *addr, socklen_t addrlen, uint16_t port); +/// Format sockaddr into caller-provided buffer, returns length written (excluding null) +size_t format_sockaddr_to(const struct sockaddr *addr_ptr, socklen_t len, std::span buf); + #if defined(USE_ESP8266) && defined(USE_SOCKET_IMPL_LWIP_TCP) /// Delay that can be woken early by socket activity. /// On ESP8266, lwip callbacks set a flag and call esp_schedule() to wake the delay.