From 31b71d6f6c2dc81fa0c261545db99382d7a68d28 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 15 Aug 2021 08:19:04 -0700 Subject: getaddrinfo: implement canonname. Paul A. Patience noted that the canonname_s variable is not used in the C code. This indicates that the AI_CANONNAME functionality of getaddrinfo isn't implemented. Let's do that. * stdlib/socket.tl (sockaddr): New slot, canonname. (addrinfo): Default canonname to nil, not 0, since it is a string that may be absent. * socket.c (getaddrinfo_wrap): If the first address object has a non-null ai_canonname and it was requested via the flags, then stick that name into every returned structure. * txr.1: Documented. --- socket.c | 14 ++++++++++++-- stdlib/socket.tl | 3 ++- txr.1 | 27 +++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 5 deletions(-) diff --git a/socket.c b/socket.c index c4745241..37158052 100644 --- a/socket.c +++ b/socket.c @@ -207,7 +207,9 @@ static val getaddrinfo_wrap(val node_in, val service_in, val hints_in) uw_catch_end; if (res == 0) { + val canonname = nil; for (aiter = alist; aiter; aiter = aiter->ai_next) { + val addr = nil; switch (aiter->ai_family) { case AF_INET: { @@ -216,7 +218,7 @@ static val getaddrinfo_wrap(val node_in, val service_in, val hints_in) ipv4_addr_from_num(&sa->sin_addr, node); if (svc_num_p) sa->sin_port = htons(c_num(service, self)); - ptail = list_collect(ptail, sockaddr_in_unpack(sa)); + addr = sockaddr_in_unpack(sa); } break; case AF_INET6: @@ -226,10 +228,18 @@ static val getaddrinfo_wrap(val node_in, val service_in, val hints_in) ipv6_addr_from_num(&sa->sin6_addr, node); if (svc_num_p) sa->sin6_port = ntohs(c_num(service, self)); - ptail = list_collect(ptail, sockaddr_in6_unpack(sa)); + addr = sockaddr_in6_unpack(sa); } break; } + if (addr) { + if (aiter == alist && (hints_ai.ai_flags & AI_CANONNAME) != 0 + && aiter->ai_canonname) + canonname = string_utf8(aiter->ai_canonname); + if (canonname) + slotset(addr, canonname_s, canonname); + ptail = list_collect(ptail, addr); + } } } diff --git a/stdlib/socket.tl b/stdlib/socket.tl index 58f81e61..e07bea6b 100644 --- a/stdlib/socket.tl +++ b/stdlib/socket.tl @@ -25,6 +25,7 @@ ;; OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. (defstruct sockaddr nil + canonname ;; from getaddrinfo (:static family nil)) (defstruct sockaddr-in sockaddr @@ -46,7 +47,7 @@ (family 0) (socktype 0) (protocol 0) - (canonname 0)) + canonname) (defvarl shut-rd 0) (defvarl shut-wr 1) diff --git a/txr.1 b/txr.1 index dfffc1b9..a45dae78 100644 --- a/txr.1 +++ b/txr.1 @@ -70174,6 +70174,7 @@ newly created datagram socket which is returned. .coNP Structure @ sockaddr .synb .mets (defstruct sockaddr nil +.mets \ \ canonname .mets \ \ (:static family nil)) .syne .desc @@ -70186,11 +70187,22 @@ several other types are derived: and .codn sockaddr-un . -It has a single slot called +It has a single static slot named .code family -which is static, and initialized to +and a single instance slot +.codn canonname , +both initialized to .codn nil . +Note: the +.code canonname +slot is optionally by the +.code getaddrinfo +function on address structures that it returns, if requested via the +.code ai-canonname +flag. The slot only provides information to the application, playing no +semantic role in addressing. + .coNP Structure @ sockaddr-in .synb .mets (defstruct sockaddr-in sockaddr @@ -70372,6 +70384,7 @@ flags: values given by the variables. .codn ai-passive , .codn ai-numerichost , .codn ai-v4mapped , +.codn ai-canonname , .codn ai-all , .code ai-addrconfig and @@ -70381,6 +70394,16 @@ These correspond to the C constants .code AI_NUMERICHOST and so forth. +If +.code ai-canonname +is specified, then every returned address structure will have its +.code canonname +member set to a string value rather than +.codn nil . +This string is a copy of the canonical name reported by the underlying +C library function, which that function places only into the first +returned address structure. + The .code family slot holds an address family, which may be the value of -- cgit v1.2.3