mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 12:57:35 +00:00
LibC: Implement gethostbyname() by talking to the DNSLookupServer.
We now talk to the lookup server over a local socket and it does the lookup on our behalf. Including some retry logic, which is nice, because it seems like DNS requests disappear in the ether pretty damn often where I am.
This commit is contained in:
parent
3ecfde193a
commit
0e4a1936ca
7 changed files with 213 additions and 36 deletions
|
@ -3,29 +3,83 @@
|
|||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <AK/Assertions.h>
|
||||
#include <AK/AKString.h>
|
||||
#include <Kernel/IPv4.h>
|
||||
|
||||
extern "C" {
|
||||
|
||||
static hostent __gethostbyname_buffer;
|
||||
static char __gethostbyname_name_buffer[512];
|
||||
static in_addr_t __gethostbyname_address;
|
||||
static in_addr_t* __gethostbyname_address_list_buffer[2];
|
||||
|
||||
hostent* gethostbyname(const char* name)
|
||||
{
|
||||
if (!strcmp(name, "boards.4channel.org")) {
|
||||
__gethostbyname_buffer.h_name = "boards.4channel.org";
|
||||
__gethostbyname_buffer.h_aliases = nullptr;
|
||||
__gethostbyname_buffer.h_addrtype = AF_INET;
|
||||
__gethostbyname_address = 0x4b4f1168;
|
||||
__gethostbyname_address_list_buffer[0] = &__gethostbyname_address;
|
||||
__gethostbyname_address_list_buffer[1] = nullptr;
|
||||
__gethostbyname_buffer.h_addr_list = (char**)__gethostbyname_address_list_buffer;
|
||||
__gethostbyname_buffer.h_length = 4;
|
||||
return &__gethostbyname_buffer;
|
||||
int fd = socket(AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0);
|
||||
if (fd < 0) {
|
||||
perror("socket");
|
||||
return nullptr;
|
||||
}
|
||||
dbgprintf("FIXME(LibC): gethostbyname(%s)\n", name);
|
||||
return nullptr;
|
||||
|
||||
sockaddr_un address;
|
||||
address.sun_family = AF_LOCAL;
|
||||
strcpy(address.sun_path, "/tmp/.DNSLookupServer-socket");
|
||||
|
||||
int retries = 3;
|
||||
int rc = 0;
|
||||
while (retries) {
|
||||
rc = connect(fd, (const sockaddr*)&address, sizeof(address));
|
||||
if (rc == 0)
|
||||
break;
|
||||
--retries;
|
||||
sleep(1);
|
||||
}
|
||||
|
||||
if (rc < 0) {
|
||||
close(fd);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
auto line = String::format("%s\n", name);
|
||||
int nsent = write(fd, line.characters(), line.length());
|
||||
if (nsent < 0) {
|
||||
perror("send");
|
||||
close(fd);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ASSERT(nsent == line.length());
|
||||
|
||||
char buffer[1024];
|
||||
int nrecv = read(fd, buffer, sizeof(buffer) - 1);
|
||||
if (nrecv < 0) {
|
||||
perror("recv");
|
||||
close(fd);
|
||||
return nullptr;
|
||||
}
|
||||
buffer[nrecv] = '\0';
|
||||
close(fd);
|
||||
|
||||
if (!memcmp(buffer, "Not found.", sizeof("Not found.") - 1))
|
||||
return nullptr;
|
||||
|
||||
rc = inet_pton(AF_INET, buffer, &__gethostbyname_address);
|
||||
if (rc < 0)
|
||||
return nullptr;
|
||||
|
||||
strncpy(__gethostbyname_name_buffer, name, strlen(name));
|
||||
|
||||
__gethostbyname_buffer.h_name = __gethostbyname_name_buffer;
|
||||
__gethostbyname_buffer.h_aliases = nullptr;
|
||||
__gethostbyname_buffer.h_addrtype = AF_INET;
|
||||
__gethostbyname_address_list_buffer[0] = &__gethostbyname_address;
|
||||
__gethostbyname_address_list_buffer[1] = nullptr;
|
||||
__gethostbyname_buffer.h_addr_list = (char**)__gethostbyname_address_list_buffer;
|
||||
__gethostbyname_buffer.h_length = 4;
|
||||
|
||||
return &__gethostbyname_buffer;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue