Don't tarpit localhost connections
[tinc] / src / netutl.c
index e2ee771..6654f97 100644 (file)
 
 bool hostnames = false;
 
+uint16_t service_to_port(const char *service) {
+       struct addrinfo *ai = str2addrinfo("localhost", service, SOCK_STREAM);
+
+       if(!ai || !ai->ai_addr) {
+               return 0;
+       }
+
+       sockaddr_t sa;
+       memcpy(&sa, ai->ai_addr, ai->ai_addrlen);
+       freeaddrinfo(ai);
+
+       switch(sa.sa.sa_family) {
+       case AF_INET:
+               return ntohs(sa.in.sin_port);
+
+       case AF_INET6:
+               return ntohs(sa.in6.sin6_port);
+
+       default:
+               logger(DEBUG_ALWAYS, LOG_WARNING, "Unknown address family %d for service %s.", sa.sa.sa_family, service);
+               return 0;
+       }
+}
+
 /*
   Turn a string into a struct addrinfo.
   Return NULL on failure.
@@ -276,3 +300,37 @@ void sockaddr_setport(sockaddr_t *sa, const char *port) {
                return;
        }
 }
+
+bool is_local_connection(const sockaddr_t *sa) {
+       switch(sa->sa.sa_family) {
+       case AF_INET:
+               // 127.0.0.0/8
+               return ntohl(sa->in.sin_addr.s_addr) >> 24 == 127;
+
+       case AF_INET6:
+               return IN6_IS_ADDR_LOOPBACK(&sa->in6.sin6_addr);
+
+       case AF_UNIX:
+               return true;
+
+       default:
+               return false;
+       }
+}
+
+uint16_t get_bound_port(int sockfd) {
+       sockaddr_t sa;
+       socklen_t salen = sizeof(sa);
+
+       if(getsockname(sockfd, (struct sockaddr *) &sa, &salen)) {
+               return 0;
+       }
+
+       if(sa.sa.sa_family == AF_INET) {
+               return ntohs(sa.in.sin_port);
+       } else  if(sa.sa.sa_family == AF_INET6) {
+               return ntohs(sa.in6.sin6_port);
+       } else {
+               return 0;
+       }
+}