Quellcode durchsuchen

LookupServer+LibC: Pass IP addresses in binary

Now that we no longer depend on the textual IPC format, we can pass IP addresses
in the format most code actually has and needs it: in binary. The only places we
actually have to deal with textual address representation is:

* When reading /etc/hosts, we have to parse textual addresses & convert them to
  binary;
* When doing reverse lookups, we have to form a pseudo-hostname of the form
  x.x.x.x.in-addr.arpa.

So we do the conversion in those two cases.

This also increases uniformity between how we handle A (IPv4 address) and other
resource record types. Namely, we now store the raw binary data as received from
a DNS server.
Sergey Bugaev vor 4 Jahren
Ursprung
Commit
d8967e4dff

+ 7 - 13
Userland/Libraries/LibC/netdb.cpp

@@ -181,19 +181,14 @@ hostent* gethostbyname(const char* name)
         return nullptr;
         return nullptr;
     }
     }
     ASSERT((size_t)nrecv == sizeof(response_length));
     ASSERT((size_t)nrecv == sizeof(response_length));
+    ASSERT(response_length == sizeof(__gethostbyname_address));
 
 
-    char response[response_length + 1];
-    nrecv = read(fd, response, response_length);
+    nrecv = read(fd, &__gethostbyname_address, response_length);
     if (nrecv < 0) {
     if (nrecv < 0) {
         perror("recv");
         perror("recv");
         return nullptr;
         return nullptr;
     }
     }
     ASSERT(nrecv == response_length);
     ASSERT(nrecv == response_length);
-    response[response_length] = 0;
-
-    int rc = inet_pton(AF_INET, response, &__gethostbyname_address);
-    if (rc <= 0)
-        return nullptr;
 
 
     gethostbyname_name_buffer = name;
     gethostbyname_name_buffer = name;
     __gethostbyname_buffer.h_name = const_cast<char*>(gethostbyname_name_buffer.characters());
     __gethostbyname_buffer.h_name = const_cast<char*>(gethostbyname_name_buffer.characters());
@@ -230,8 +225,7 @@ hostent* gethostbyaddr(const void* addr, socklen_t addr_size, int type)
         close(fd);
         close(fd);
     });
     });
 
 
-    IPv4Address ipv4_address((const u8*)&((const in_addr*)addr)->s_addr);
-    auto address = ipv4_address.to_string();
+    const in_addr_t& in_addr = ((const struct in_addr*)addr)->s_addr;
 
 
     struct [[gnu::packed]] {
     struct [[gnu::packed]] {
         u32 message_size;
         u32 message_size;
@@ -239,10 +233,10 @@ hostent* gethostbyaddr(const void* addr, socklen_t addr_size, int type)
         i32 message_id;
         i32 message_id;
         i32 address_length;
         i32 address_length;
     } request_header = {
     } request_header = {
-        sizeof(request_header) - sizeof(request_header.message_size) + address.length(),
+        sizeof(request_header) - sizeof(request_header.message_size) + sizeof(in_addr),
         lookup_server_endpoint_magic,
         lookup_server_endpoint_magic,
         3,
         3,
-        (i32)address.length(),
+        (i32)sizeof(in_addr),
     };
     };
     int nsent = write(fd, &request_header, sizeof(request_header));
     int nsent = write(fd, &request_header, sizeof(request_header));
     if (nsent < 0) {
     if (nsent < 0) {
@@ -250,12 +244,12 @@ hostent* gethostbyaddr(const void* addr, socklen_t addr_size, int type)
         return nullptr;
         return nullptr;
     }
     }
     ASSERT((size_t)nsent == sizeof(request_header));
     ASSERT((size_t)nsent == sizeof(request_header));
-    nsent = write(fd, address.characters(), address.length());
+    nsent = write(fd, &in_addr, sizeof(in_addr));
     if (nsent < 0) {
     if (nsent < 0) {
         perror("write");
         perror("write");
         return nullptr;
         return nullptr;
     }
     }
-    ASSERT((size_t)nsent == address.length());
+    ASSERT((size_t)nsent == sizeof(in_addr));
 
 
     struct [[gnu::packed]] {
     struct [[gnu::packed]] {
         u32 message_size;
         u32 message_size;

+ 2 - 3
Userland/Services/LookupServer/ClientConnection.cpp

@@ -58,10 +58,9 @@ OwnPtr<Messages::LookupServer::LookupNameResponse> ClientConnection::handle(cons
 
 
 OwnPtr<Messages::LookupServer::LookupAddressResponse> ClientConnection::handle(const Messages::LookupServer::LookupAddress& message)
 OwnPtr<Messages::LookupServer::LookupAddressResponse> ClientConnection::handle(const Messages::LookupServer::LookupAddress& message)
 {
 {
-    auto optional_address = IPv4Address::from_string(message.address());
-    if (!optional_address.has_value())
+    if (message.address().length() != 4)
         return make<Messages::LookupServer::LookupAddressResponse>(1, String());
         return make<Messages::LookupServer::LookupAddressResponse>(1, String());
-    auto& address = optional_address.value();
+    IPv4Address address { (const u8*)message.address().characters() };
     auto name = String::formatted("{}.{}.{}.{}.in-addr.arpa",
     auto name = String::formatted("{}.{}.{}.{}.in-addr.arpa",
         address[3],
         address[3],
         address[2],
         address[2],

+ 1 - 2
Userland/Services/LookupServer/DNSResponse.cpp

@@ -108,8 +108,7 @@ Optional<DNSResponse> DNSResponse::from_raw_response(const u8* raw_data, size_t
             size_t dummy_offset = offset;
             size_t dummy_offset = offset;
             data = parse_dns_name(raw_data, dummy_offset, raw_size);
             data = parse_dns_name(raw_data, dummy_offset, raw_size);
         } else if (record.type() == T_A) {
         } else if (record.type() == T_A) {
-            auto ipv4_address = IPv4Address((const u8*)record.data());
-            data = ipv4_address.to_string();
+            data = { record.data(), record.data_length() };
         } else {
         } else {
             // FIXME: Parse some other record types perhaps?
             // FIXME: Parse some other record types perhaps?
             dbgln("data=(unimplemented record type {})", record.type());
             dbgln("data=(unimplemented record type {})", record.type());

+ 2 - 1
Userland/Services/LookupServer/LookupServer.cpp

@@ -96,9 +96,10 @@ void LookupServer::load_etc_hosts()
             (u8)atoi(sections[2].characters()),
             (u8)atoi(sections[2].characters()),
             (u8)atoi(sections[3].characters()),
             (u8)atoi(sections[3].characters()),
         };
         };
+        auto raw_addr = addr.to_in_addr_t();
 
 
         auto name = fields[1];
         auto name = fields[1];
-        m_etc_hosts.set(name, addr.to_string());
+        m_etc_hosts.set(name, String { (const char*)&raw_addr, sizeof(raw_addr) });
 
 
         IPv4Address reverse_addr {
         IPv4Address reverse_addr {
             (u8)atoi(sections[3].characters()),
             (u8)atoi(sections[3].characters()),