Add AbslStringify to IPAddress

This allows IPAddress objects to be used with absl::StrCat and other
formatting tools. The implementation prefixes the address with the
family type:
- "ipv4:" for AF_INET
- "ipv6:" for AF_INET6
- "unspecified" for AF_UNSPEC
- "unknown:<family>:" for other families

Bug: None
Change-Id: Icb30eab5b742d2ab22628ec84f2e52636b1ebc42
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/463500
Reviewed-by: Danil Chapovalov <danilchap@webrtc.org>
Commit-Queue: Harald Alvestrand <hta@webrtc.org>
Cr-Commit-Position: refs/heads/main@{#47398}
diff --git a/rtc_base/BUILD.gn b/rtc_base/BUILD.gn
index 452bf34..94a87d5 100644
--- a/rtc_base/BUILD.gn
+++ b/rtc_base/BUILD.gn
@@ -937,6 +937,7 @@
     ":net_helpers",
     ":stringutils",
     "system:rtc_export",
+    "//third_party/abseil-cpp/absl/strings",
     "//third_party/abseil-cpp/absl/strings:string_view",
   ]
   if (is_win) {
diff --git a/rtc_base/ip_address.h b/rtc_base/ip_address.h
index daf5620..7ebad47 100644
--- a/rtc_base/ip_address.h
+++ b/rtc_base/ip_address.h
@@ -15,6 +15,7 @@
 #include <cstring>
 #include <string>
 
+#include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
 #include "rtc_base/byte_order.h"
 #include "rtc_base/net_helpers.h"
@@ -128,6 +129,29 @@
   // Whether this is an unspecified IP address.
   bool IsNil() const;
 
+  template <typename Sink>
+  friend void AbslStringify(Sink& sink, const IPAddress& ip) {
+    switch (ip.family_) {
+      case AF_INET:
+        sink.Append("ipv4:");
+        sink.Append(ip.ToString());
+        break;
+      case AF_INET6:
+        sink.Append("ipv6:");
+        sink.Append(ip.ToString());
+        break;
+      case AF_UNSPEC:
+        sink.Append("unspecified");
+        break;
+      default:
+        sink.Append("unknown:");
+        sink.Append(absl::StrCat(ip.family_));
+        sink.Append(":");
+        sink.Append(ip.ToString());
+        break;
+    }
+  }
+
  private:
   int family_;
   union {
diff --git a/rtc_base/ip_address_unittest.cc b/rtc_base/ip_address_unittest.cc
index b4ad770..1e91727 100644
--- a/rtc_base/ip_address_unittest.cc
+++ b/rtc_base/ip_address_unittest.cc
@@ -13,6 +13,7 @@
 #include <cstring>
 #include <string>
 
+#include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
 #include "rtc_base/byte_order.h"
 #include "rtc_base/net_helpers.h"
@@ -983,4 +984,15 @@
   EXPECT_NE(addr1, addr5);
 }
 
+TEST(IPAddressTest, AbslStringify) {
+  IPAddress addr_v4(kIPv4PublicAddr);
+  EXPECT_EQ(absl::StrCat(addr_v4), "ipv4:" + kIPv4PublicAddrString);
+
+  IPAddress addr_v6(kIPv6PublicAddr);
+  EXPECT_EQ(absl::StrCat(addr_v6), "ipv6:" + kIPv6PublicAddrString);
+
+  IPAddress addr_unspec;
+  EXPECT_EQ(absl::StrCat(addr_unspec), "unspecified");
+}
+
 }  // namespace webrtc