Petr Pisar's privoxy-3.0.12-ipv6-3.diff.
[privoxy.git] / jbsockets.c
index 6f66e1c..76f1cb8 100644 (file)
@@ -1,4 +1,4 @@
-const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.44 2007/09/15 13:01:31 fabiankeil Exp $";
+const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.50 2008/12/20 14:53:55 fabiankeil Exp $";
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/jbsockets.c,v $
@@ -35,6 +35,30 @@ const char jbsockets_rcs[] = "$Id: jbsockets.c,v 1.44 2007/09/15 13:01:31 fabian
  *
  * Revisions   :
  *    $Log: jbsockets.c,v $
+ *    Revision 1.50  2008/12/20 14:53:55  fabiankeil
+ *    Add config option socket-timeout to control the time
+ *    Privoxy waits for data to arrive on a socket. Useful
+ *    in case of stale ssh tunnels or when fuzz-testing.
+ *
+ *    Revision 1.49  2008/11/10 17:03:57  fabiankeil
+ *    Fix a gcc44 warning and remove a now-obsolete cast.
+ *
+ *    Revision 1.48  2008/09/04 08:13:58  fabiankeil
+ *    Prepare for critical sections on Windows by adding a
+ *    layer of indirection before the pthread mutex functions.
+ *
+ *    Revision 1.47  2008/03/26 18:07:07  fabiankeil
+ *    Add hostname directive. Closes PR#1918189.
+ *
+ *    Revision 1.46  2008/03/21 11:13:57  fabiankeil
+ *    Only gather host information if it's actually needed.
+ *    Also move the code out of accept_connection() so it's less likely
+ *    to delay other incoming connections if the host is misconfigured.
+ *
+ *    Revision 1.45  2007/09/30 16:59:22  fabiankeil
+ *    Set the maximum listen() backlog to 128. Apparently SOMAXCONN is
+ *    neither high enough, nor a hard limit on mingw32. Again for BR#1795281.
+ *
  *    Revision 1.44  2007/09/15 13:01:31  fabiankeil
  *    Increase listen() backlog to SOMAXCONN (or 128) to decrease
  *    chances of dropped connections under load. Problem reported
@@ -323,7 +347,7 @@ const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION;
  *
  * Parameters  :
  *          1  :  host = hostname to connect to
- *          2  :  portnum = port to connent on
+ *          2  :  portnum = port to connent on (XXX: should be unsigned)
  *          3  :  csp = Current client state (buffers, headers, etc...)
  *                      Not modified, only used for source IP and ACL.
  *
@@ -331,11 +355,182 @@ const char jbsockets_h_rcs[] = JBSOCKETS_H_VERSION;
  *                file descriptor.
  *
  *********************************************************************/
+#ifdef HAVE_GETADDRINFO
+/* Getaddrinfo implementation */
+jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
+{
+   struct addrinfo hints, *result, *rp;
+   char service[6];
+   int retval;
+   jb_socket fd;
+   fd_set wfds;
+   struct timeval tv[1];
+#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA)
+   int   flags;
+#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */
+   int connect_failed;
+
+#ifdef FEATURE_ACL
+   struct access_control_addr dst[1];
+#endif /* def FEATURE_ACL */
+
+   retval = snprintf(service, sizeof(service), "%d", portnum);
+   if (-1 == retval || sizeof(service) <= retval)
+   {
+      log_error(LOG_LEVEL_ERROR,
+            "Port number (%d) ASCII decimal representation doesn't fit into 6 bytes",
+            portnum);
+      csp->http->host_ip_addr_str = strdup("unknown");
+      return(JB_INVALID_SOCKET);
+   }
+
+   memset((char *)&hints, 0, sizeof hints);
+   hints.ai_family = AF_UNSPEC;
+   hints.ai_socktype = SOCK_STREAM;
+   hints.ai_flags = AI_ADDRCONFIG | AI_NUMERICSERV; /* avoid service look-up */
+   if ((retval = getaddrinfo(host, service, &hints, &result)))
+   {
+      log_error(LOG_LEVEL_INFO,
+            "Can not resolve %s: %s", host, gai_strerror(retval));
+      csp->http->host_ip_addr_str = strdup("unknown");
+      return(JB_INVALID_SOCKET);
+   }
+
+   for (rp = result; rp != NULL; rp = rp->ai_next)
+   {
+
+#ifdef FEATURE_ACL
+      memcpy(&dst->addr, rp->ai_addr, rp->ai_addrlen);
+
+      if (block_acl(dst, csp))
+      {
+#ifdef __OS2__
+         errno = SOCEPERM;
+#else
+         errno = EPERM;
+#endif
+         continue;
+      }
+#endif /* def FEATURE_ACL */
+
+      csp->http->host_ip_addr_str = malloc(NI_MAXHOST);
+      retval = getnameinfo(rp->ai_addr, rp->ai_addrlen,
+            csp->http->host_ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+      if (!csp->http->host_ip_addr_str || retval)
+      {
+         log_error(LOG_LEVEL_ERROR, "Can not save csp->http->host_ip_addr_str: %s",
+               (csp->http->host_ip_addr_str) ? gai_strerror(retval) :
+               "Insufficient memory");
+         freez(csp->http->host_ip_addr_str);
+         continue;
+      }
+
+#ifdef _WIN32
+      if ((fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) ==
+            JB_INVALID_SOCKET)
+#else
+      if ((fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol)) < 0)
+#endif
+      {
+         continue;
+      }
+
+#ifdef TCP_NODELAY
+      {  /* turn off TCP coalescence */
+         int mi = 1;
+         setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *) &mi, sizeof (int));
+      }
+#endif /* def TCP_NODELAY */
+
+#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
+      if ((flags = fcntl(fd, F_GETFL, 0)) != -1)
+      {
+         flags |= O_NDELAY;
+         fcntl(fd, F_SETFL, flags);
+      }
+#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
+
+      connect_failed = 0;
+      while (connect(fd, rp->ai_addr, rp->ai_addrlen) == JB_INVALID_SOCKET)
+      {
+#ifdef _WIN32
+         if (errno == WSAEINPROGRESS)
+#elif __OS2__ 
+         if (sock_errno() == EINPROGRESS)
+#else /* ifndef _WIN32 */
+         if (errno == EINPROGRESS)
+#endif /* ndef _WIN32 || __OS2__ */
+         {
+            break;
+         }
+
+#ifdef __OS2__ 
+         if (sock_errno() != EINTR)
+#else
+         if (errno != EINTR)
+#endif /* __OS2__ */
+         {
+            close_socket(fd);
+            connect_failed = 1;
+            break;
+         }
+      }
+      if (connect_failed)
+      {
+         continue;
+      }
+
+#if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__)
+      if (flags != -1)
+      {
+         flags &= ~O_NDELAY;
+         fcntl(fd, F_SETFL, flags);
+      }
+#endif /* !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) */
+
+      /* wait for connection to complete */
+      FD_ZERO(&wfds);
+      FD_SET(fd, &wfds);
+
+      tv->tv_sec  = 30;
+      tv->tv_usec = 0;
+
+      /* MS Windows uses int, not SOCKET, for the 1st arg of select(). Wierd! */
+      if (select((int)fd + 1, NULL, &wfds, NULL, tv) <= 0)
+      {
+         close_socket(fd);
+         continue;
+      }
+      
+      break; /* for; Connection established; don't try other addresses */
+   }
+
+   freeaddrinfo(result);
+   if (!rp)
+   {
+      log_error(LOG_LEVEL_INFO, "Could not connect to TCP/[%s]:%s", host, service);
+      return(JB_INVALID_SOCKET);
+   }
+   /* XXX: Current connection verification (EINPROGRESS && select() for
+    * writing) is not sufficient. E.g. on my Linux-2.6.27 with glibc-2.6
+    * select returns socket ready for writing, however subsequential write(2)
+    * fails with ENOCONNECT. Read Linux connect(2) man page about non-blocking
+    * sockets.
+    * Thus we can not log here the socket is connected. */
+   /*log_error(LOG_LEVEL_INFO, "Connected to TCP/[%s]:%s", host, service);*/
+
+   return(fd);
+
+}
+
+# else /* ndef HAVE_GETADDRINFO */
+/* Pre-getaddrinfo implementation */
+
 jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
 {
    struct sockaddr_in inaddr;
    jb_socket fd;
-   int addr;
+   unsigned int addr;
    fd_set wfds;
    struct timeval tv[1];
 #if !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA)
@@ -355,7 +550,7 @@ jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
    }
 
 #ifdef FEATURE_ACL
-   dst->addr = ntohl((unsigned long) addr);
+   dst->addr = ntohl(addr);
    dst->port = portnum;
 
    if (block_acl(dst, csp))
@@ -458,6 +653,7 @@ jb_socket connect_to(const char *host, int portnum, struct client_state *csp)
    return(fd);
 
 }
+#endif /* ndef HAVE_GETADDRINFO */
 
 
 /*********************************************************************
@@ -567,6 +763,46 @@ int read_socket(jb_socket fd, char *buf, int len)
 }
 
 
+/*********************************************************************
+ *
+ * Function    :  data_is_available
+ *
+ * Description :  Waits for data to arrive on a socket.
+ *
+ * Parameters  :
+ *          1  :  fd = file descriptor of the socket to read
+ *          2  :  seconds_to_wait = number of seconds after which we give up.
+ *
+ * Returns     :  TRUE if data arrived in time,
+ *                FALSE otherwise.
+ *
+ *********************************************************************/
+int data_is_available(jb_socket fd, int seconds_to_wait)
+{
+   fd_set rfds;
+   struct timeval timeout;
+   int n;
+
+   memset(&timeout, 0, sizeof(timeout));
+   timeout.tv_sec = seconds_to_wait;
+
+#ifdef __OS2__
+   /* Copy and pasted from jcc.c ... */
+   memset(&rfds, 0, sizeof(fd_set));
+#else
+   FD_ZERO(&rfds);
+#endif
+   FD_SET(fd, &rfds);
+
+   n = select(fd+1, &rfds, NULL, NULL, &timeout);
+
+   /*
+    * XXX: Do we care about the different error conditions?
+    */
+   return (n == 1);
+}
+
+
 /*********************************************************************
  *
  * Function    :  close_socket
@@ -613,7 +849,16 @@ void close_socket(jb_socket fd)
  *********************************************************************/
 int bind_port(const char *hostnam, int portnum, jb_socket *pfd)
 {
+#ifdef HAVE_GETADDRINFO
+   struct addrinfo hints;
+   struct addrinfo *result, *rp;
+   /* TODO: portnum shuld be string to allow symbolic service names in
+    * configuration and to avoid following int2string */
+   char servnam[6];
+   int retval;
+#else
    struct sockaddr_in inaddr;
+#endif /* def HAVE_GETADDRINFO */
    jb_socket fd;
 #ifndef _WIN32
    int one = 1;
@@ -621,6 +866,32 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd)
 
    *pfd = JB_INVALID_SOCKET;
 
+#ifdef HAVE_GETADDRINFO
+   retval = snprintf(servnam, sizeof(servnam), "%d", portnum);
+   if (-1 == retval || sizeof(servnam) <= retval)
+   {
+      log_error(LOG_LEVEL_ERROR,
+            "Port number (%d) ASCII decimal representation doesn't fit into 6 bytes",
+            portnum);
+      return -1;
+   }
+
+   memset(&hints, 0, sizeof(struct addrinfo));
+   hints.ai_family=AF_UNSPEC;
+   hints.ai_socktype=SOCK_STREAM;
+   hints.ai_flags=AI_PASSIVE|AI_ADDRCONFIG;
+   hints.ai_protocol=0; /* Realy any stream protocol or TCP only */
+   hints.ai_canonname=NULL;
+   hints.ai_addr=NULL;
+   hints.ai_next=NULL;
+
+   if ((retval = getaddrinfo(hostnam, servnam, &hints, &result)))
+   {
+      log_error(LOG_LEVEL_ERROR,
+            "Can not resolve %s: %s", hostnam, gai_strerror(retval));
+      return -2;
+   }
+#else
    memset((char *)&inaddr, '\0', sizeof inaddr);
 
    inaddr.sin_family      = AF_INET;
@@ -643,8 +914,15 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd)
       inaddr.sin_port = htonl((unsigned long) portnum);
    }
 #endif /* ndef _WIN32 */
+#endif /* def HAVE_GETADDRINFO */
 
+#ifdef HAVE_GETADDRINFO
+   for (rp = result; rp != NULL; rp = rp->ai_next)
+   {
+      fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol);
+#else
    fd = socket(AF_INET, SOCK_STREAM, 0);
+#endif /* def HAVE_GETADDRINFO */
 
 #ifdef _WIN32
    if (fd == JB_INVALID_SOCKET)
@@ -652,7 +930,11 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd)
    if (fd < 0)
 #endif
    {
+#ifdef HAVE_GETADDRINFO
+      continue;
+#else
       return(-1);
+#endif
    }
 
 #ifndef _WIN32
@@ -671,7 +953,11 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd)
    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&one, sizeof(one));
 #endif /* ndef _WIN32 */
 
+#ifdef HAVE_GETADDRINFO
+   if (bind(fd, rp->ai_addr, rp->ai_addrlen) < 0)
+#else
    if (bind(fd, (struct sockaddr *)&inaddr, sizeof(inaddr)) < 0)
+#endif
    {
 #ifdef _WIN32
       errno = WSAGetLastError();
@@ -680,15 +966,36 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd)
       if (errno == EADDRINUSE)
 #endif
       {
+#ifdef HAVE_GETADDRINFO
+         freeaddrinfo(result);
+#endif
          close_socket(fd);
          return(-3);
       }
       else
       {
          close_socket(fd);
+#ifndef HAVE_GETADDRINFO
          return(-1);
       }
    }
+#else
+      }
+   }
+   else
+      /* bind() succeeded, escape from for-loop */
+      /* TODO: Support multiple listening sockets (e.g. localhost resolves to
+       * AF_INET and AF_INET6, but only fist address is used */
+      break;
+   }
+
+   freeaddrinfo(result);
+   if (rp == NULL)
+   {
+      /* All bind()s failed */
+      return(-1);
+   }
+#endif /* ndef HAVE_GETADDRINFO */
 
    while (listen(fd, MAX_LISTEN_BACKLOG) == -1)
    {
@@ -706,31 +1013,42 @@ int bind_port(const char *hostnam, int portnum, jb_socket *pfd)
 
 /*********************************************************************
  *
- * Function    :  accept_connection
+ * Function    :  get_host_information
  *
- * Description :  Accepts a connection on a socket.  Socket must have
- *                been created using bind_port().
+ * Description :  Determines the IP address the client used to
+ *                reach us and the hostname associated with it.
+ *
+ *                XXX: Most of the code has been copy and pasted
+ *                from accept_connection() and not all of the
+ *                ifdefs paths have been tested afterwards.
  *
  * Parameters  :
- *          1  :  csp = Client state, cfd, ip_addr_str, and 
- *                ip_addr_long will be set by this routine.
- *          2  :  fd  = file descriptor returned from bind_port
+ *          1  :  afd = File descriptor returned from accept().
+ *          2  :  ip_address = Pointer to return the pointer to
+ *                             the ip address string.
+ *          3  :  hostname =   Pointer to return the pointer to
+ *                             the hostname or NULL if the caller
+ *                             isn't interested in it.
  *
- * Returns     :  when a connection is accepted, it returns 1 (TRUE).
- *                On an error it returns 0 (FALSE).
+ * Returns     :  void.
  *
  *********************************************************************/
-int accept_connection(struct client_state * csp, jb_socket fd)
+void get_host_information(jb_socket afd, char **ip_address, char **hostname)
 {
-   struct sockaddr_in client, server;
+#ifdef HAVE_GETNAMEINFO
+   struct sockaddr_storage server;
+   int retval;
+#else
+   struct sockaddr_in server;
    struct hostent *host = NULL;
-   jb_socket afd;
+#endif /* HAVE_GETNAMEINFO */
 #if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA)
-   /* Wierdness - fix a warning. */
-   int c_length, s_length;
+   /* according to accept_connection() this fixes a warning. */
+   int s_length, s_length_provided;
 #else
-   socklen_t c_length, s_length;
+   socklen_t s_length, s_length_provided;
 #endif
+#ifndef HAVE_GETNAMEINFO
 #if defined(HAVE_GETHOSTBYADDR_R_8_ARGS) ||  defined(HAVE_GETHOSTBYADDR_R_7_ARGS) || defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
    struct hostent result;
 #if defined(HAVE_GETHOSTBYADDR_R_5_ARGS)
@@ -740,33 +1058,52 @@ int accept_connection(struct client_state * csp, jb_socket fd)
    int thd_err;
 #endif /* def HAVE_GETHOSTBYADDR_R_5_ARGS */
 #endif /* def HAVE_GETHOSTBYADDR_R_(8|7|5)_ARGS */
+#endif /* ifndef HAVE_GETNAMEINFO */
+   s_length = s_length_provided = sizeof(server);
 
-   c_length = s_length = sizeof(client);
-
-#ifdef _WIN32
-   afd = accept (fd, (struct sockaddr *) &client, &c_length);
-   if (afd == JB_INVALID_SOCKET)
-   {
-      return 0;
-   }
-#else
-   do
-   {
-      afd = accept (fd, (struct sockaddr *) &client, &c_length);
-   } while (afd < 1 && errno == EINTR);
-   if (afd < 0)
+   if (NULL != hostname)
    {
-      return 0;
+      *hostname = NULL;
    }
-#endif
+   *ip_address = NULL;
 
-   /* 
-    * Determine the IP-Adress that the client used to reach us
-    * and the hostname associated with that address
-    */
    if (!getsockname(afd, (struct sockaddr *) &server, &s_length))
    {
-      csp->my_ip_addr_str = strdup(inet_ntoa(server.sin_addr));
+      if (s_length > s_length_provided)
+      {
+         log_error(LOG_LEVEL_ERROR, "getsockname() truncated server address");
+         return;
+      }
+#ifdef HAVE_GETNAMEINFO
+      *ip_address = malloc(NI_MAXHOST);
+      if ((retval = getnameinfo((struct sockaddr *) &server, s_length,
+                  *ip_address, NI_MAXHOST, NULL, 0, NI_NUMERICHOST))) {
+         log_error(LOG_LEVEL_ERROR, "Unable to print my own IP address: %s",
+               gai_strerror(retval));
+         freez(*ip_address);
+         return;
+      }
+#else
+      *ip_address = strdup(inet_ntoa(server.sin_addr));
+#endif /* HAVE_GETNAMEINFO */
+      if (NULL == hostname)
+      {
+         /*
+          * We're done here, the caller isn't
+          * interested in knowing the hostname.
+          */
+         return;
+      }
+
+#ifdef HAVE_GETNAMEINFO
+      *hostname = malloc(NI_MAXHOST);
+      if ((retval = getnameinfo((struct sockaddr *) &server, s_length,
+                  *hostname, NI_MAXHOST, NULL, 0, NI_NAMEREQD))) {
+         log_error(LOG_LEVEL_ERROR, "Unable to resolve my own IP address: %s",
+               gai_strerror(retval));
+         freez(*hostname);
+      }
+#else
 #if defined(HAVE_GETHOSTBYADDR_R_8_ARGS)
       gethostbyaddr_r((const char *)&server.sin_addr,
                       sizeof(server.sin_addr), AF_INET,
@@ -788,10 +1125,10 @@ int accept_connection(struct client_state * csp, jb_socket fd)
          host = NULL;
       }
 #elif FEATURE_PTHREAD
-      pthread_mutex_lock(&resolver_mutex);
+      privoxy_mutex_lock(&resolver_mutex);
       host = gethostbyaddr((const char *)&server.sin_addr, 
                            sizeof(server.sin_addr), AF_INET);
-      pthread_mutex_unlock(&resolver_mutex);
+      privoxy_mutex_unlock(&resolver_mutex);
 #else
       host = gethostbyaddr((const char *)&server.sin_addr, 
                            sizeof(server.sin_addr), AF_INET);
@@ -802,13 +1139,83 @@ int accept_connection(struct client_state * csp, jb_socket fd)
       }
       else
       {
-         csp->my_hostname = strdup(host->h_name);
+         *hostname = strdup(host->h_name);
       }
+#endif /* else def HAVE_GETNAMEINFO */
+   }
+
+   return;
+}
+
+
+/*********************************************************************
+ *
+ * Function    :  accept_connection
+ *
+ * Description :  Accepts a connection on a socket.  Socket must have
+ *                been created using bind_port().
+ *
+ * Parameters  :
+ *          1  :  csp = Client state, cfd, ip_addr_str, and 
+ *                ip_addr_long will be set by this routine.
+ *          2  :  fd  = file descriptor returned from bind_port
+ *
+ * Returns     :  when a connection is accepted, it returns 1 (TRUE).
+ *                On an error it returns 0 (FALSE).
+ *
+ *********************************************************************/
+int accept_connection(struct client_state * csp, jb_socket fd)
+{
+#ifdef HAVE_GETNAMEINFO
+   /* XXX: client is stored directly into csp->tcp_addr */
+#define client (csp->tcp_addr)
+   int retval;
+#else
+   struct sockaddr_in client;
+#endif
+   jb_socket afd;
+#if defined(_WIN32) || defined(__OS2__) || defined(__APPLE_CC__) || defined(AMIGA)
+   /* Wierdness - fix a warning. */
+   int c_length;
+#else
+   socklen_t c_length;
+#endif
+
+   c_length = sizeof(client);
+
+#ifdef _WIN32
+   afd = accept (fd, (struct sockaddr *) &client, &c_length);
+   if (afd == JB_INVALID_SOCKET)
+   {
+      return 0;
    }
+#else
+   do
+   {
+      afd = accept (fd, (struct sockaddr *) &client, &c_length);
+   } while (afd < 1 && errno == EINTR);
+   if (afd < 0)
+   {
+      return 0;
+   }
+#endif
 
-   csp->cfd    = afd;
+   csp->cfd = afd;
+#ifdef HAVE_GETNAMEINFO
+   csp->ip_addr_str = malloc(NI_MAXHOST);
+   retval = getnameinfo((struct sockaddr *) &client, c_length,
+         csp->ip_addr_str, NI_MAXHOST, NULL, 0, NI_NUMERICHOST);
+   if (!csp->ip_addr_str || retval)
+   {
+      log_error(LOG_LEVEL_ERROR, "Can not save csp->ip_addr_str: %s",
+            (csp->ip_addr_str) ? gai_strerror(retval) : "Insuffcient memory");
+      freez(csp->ip_addr_str);
+   }
+#undef client
+#else
    csp->ip_addr_str  = strdup(inet_ntoa(client.sin_addr));
    csp->ip_addr_long = ntohl(client.sin_addr.s_addr);
+#endif /* def HAVE_GETNAMEINFO */
 
    return 1;
 
@@ -884,7 +1291,7 @@ unsigned long resolve_hostname_to_ip(const char *host)
          hostp = NULL;
       }
 #elif FEATURE_PTHREAD
-      pthread_mutex_lock(&resolver_mutex);
+      privoxy_mutex_lock(&resolver_mutex);
       while (NULL == (hostp = gethostbyname(host))
              && (h_errno == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
       {   
@@ -892,7 +1299,7 @@ unsigned long resolve_hostname_to_ip(const char *host)
             "Timeout #%u while trying to resolve %s. Trying again.",
             dns_retries, host);
       }
-      pthread_mutex_unlock(&resolver_mutex);
+      privoxy_mutex_unlock(&resolver_mutex);
 #else
       while (NULL == (hostp = gethostbyname(host))
              && (h_errno == TRY_AGAIN) && (dns_retries++ < MAX_DNS_RETRIES))
@@ -939,4 +1346,6 @@ unsigned long resolve_hostname_to_ip(const char *host)
   Local Variables:
   tab-width: 3
   end:
+
+  vim:softtabstop=3 shiftwidth=3
 */