diff --git a/libc/dns/gethostbyaddr.c b/libc/dns/gethostbyaddr.c index 8f095f2d1..c7da4eead 100644 --- a/libc/dns/gethostbyaddr.c +++ b/libc/dns/gethostbyaddr.c @@ -31,23 +31,24 @@ struct hostent *gethostbyaddr(const void *s_addr, socklen_t len, int type) { static struct hostent *ptr1, he1; + static char h_name[DNS_NAME_MAX+1]; + static char* h_aliases[1]; + static char* h_addr_list[2]; + static char h_addr_list0[4]; + struct sockaddr_in addr; - char name[DNS_NAME_MAX + 1]; if (!ptr1) { - he1.h_name = NULL; + he1.h_name = h_name; - he1.h_aliases = (char **)malloc(sizeof(char *) * 1); - if (!he1.h_aliases) return NULL; + he1.h_aliases = h_aliases; he1.h_aliases[0] = NULL; he1.h_addrtype = AF_INET; he1.h_length = 4; - he1.h_addr_list = (char **)malloc(sizeof(char *) * 2); - if (!he1.h_addr_list) return NULL; + he1.h_addr_list = h_addr_list; - he1.h_addr_list[0] = (char *)malloc(sizeof(uint32_t)); - if (!he1.h_addr_list[0]) return NULL; + he1.h_addr_list[0] = h_addr_list0; he1.h_addr_list[1] = NULL; ptr1 = &he1; @@ -58,12 +59,10 @@ struct hostent *gethostbyaddr(const void *s_addr, socklen_t len, int type) { addr.sin_port = 0; addr.sin_addr.s_addr = *(uint32_t *)(s_addr); - if (getnameinfo((struct sockaddr *)&addr, sizeof(addr), name, sizeof(name), - NULL, 0, 0)) + if (getnameinfo((struct sockaddr *)&addr, sizeof(addr), ptr1->h_name, + DNS_NAME_MAX, NULL, 0, 0)) return NULL; - if (ptr1->h_name) free(ptr1->h_name); - ptr1->h_name = strdup(name); *((uint32_t *)ptr1->h_addr_list[0]) = (addr.sin_addr.s_addr); return ptr1; diff --git a/libc/dns/gethostbyname.c b/libc/dns/gethostbyname.c index 0153771ed..cc7d4365e 100644 --- a/libc/dns/gethostbyname.c +++ b/libc/dns/gethostbyname.c @@ -27,26 +27,28 @@ ╚─────────────────────────────────────────────────────────────────────────────*/ #include "libc/dns/ent.h" #include "libc/mem/mem.h" +#include "libc/str/str.h" #include "libc/sysv/consts/af.h" struct hostent *gethostbyname(const char *name) { static struct hostent *ptr0, he0; + static char h_name[DNS_NAME_MAX + 1]; + static char *h_aliases[1]; + static char *h_addr_list[2]; + static char h_addr_list0[4]; struct addrinfo *result = NULL; if (!ptr0) { - he0.h_name = NULL; + he0.h_name = h_name; - he0.h_aliases = (char **)malloc(sizeof(char *) * 1); - if (!he0.h_aliases) return NULL; + he0.h_aliases = h_aliases; he0.h_aliases[0] = NULL; he0.h_addrtype = AF_INET; he0.h_length = 4; - he0.h_addr_list = (char **)malloc(sizeof(char *) * 2); - if (!he0.h_addr_list) return NULL; + he0.h_addr_list = h_addr_list; - he0.h_addr_list[0] = (char *)malloc(sizeof(uint32_t)); - if (!he0.h_addr_list[0]) return NULL; + he0.h_addr_list[0] = h_addr_list0; he0.h_addr_list[1] = NULL; ptr0 = &he0; @@ -54,12 +56,12 @@ struct hostent *gethostbyname(const char *name) { if (getaddrinfo(name, NULL, NULL, &result) || result == NULL) return NULL; - if (ptr0->h_name) free(ptr0->h_name); - if (result->ai_canonname && strlen(result->ai_canonname) > 0) { - ptr0->h_name = strdup(result->ai_canonname); - } else { - ptr0->h_name = strdup(name); - } + /* if getaddrinfo is successful, result->ai_canonname is non-NULL, + * (see newaddrinfo) but the string can still be empty */ + if (result->ai_canonname[0]) + memccpy(ptr0->h_name, result->ai_canonname, '\0', DNS_NAME_MAX); + else + memccpy(ptr0->h_name, name, '\0', DNS_NAME_MAX); *((uint32_t *)ptr0->h_addr_list[0]) = (result->ai_addr4->sin_addr.s_addr); /* TODO: if result has ai_next, fit multiple entries for h_addr_list */