+
+
+pa_bool_t pa_socket_address_is_local(const struct sockaddr *sa) {
+ pa_assert(sa);
+
+ switch (sa->sa_family) {
+ case AF_UNIX:
+ return TRUE;
+
+ case AF_INET:
+ return ((const struct sockaddr_in*) sa)->sin_addr.s_addr == INADDR_LOOPBACK;
+
+#ifdef HAVE_IPV6
+ case AF_INET6:
+ return memcmp(&((const struct sockaddr_in6*) sa)->sin6_addr, &in6addr_loopback, sizeof(struct in6_addr)) == 0;
+#endif
+
+ default:
+ return FALSE;
+ }
+}
+
+pa_bool_t pa_socket_is_local(int fd) {
+
+ union {
+ struct sockaddr_storage storage;
+ struct sockaddr sa;
+ struct sockaddr_in in;
+#ifdef HAVE_IPV6
+ struct sockaddr_in6 in6;
+#endif
+#ifdef HAVE_SYS_UN_H
+ struct sockaddr_un un;
+#endif
+ } sa;
+ socklen_t sa_len = sizeof(sa);
+
+ if (getpeername(fd, &sa.sa, &sa_len) < 0)
+ return FALSE;
+
+ return pa_socket_address_is_local(&sa.sa);
+}