Index: includes/bootstrap.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/bootstrap.inc,v
retrieving revision 1.206
diff -u -r1.206 bootstrap.inc
--- includes/bootstrap.inc	10 Jan 2008 22:47:17 -0000	1.206
+++ includes/bootstrap.inc	10 Feb 2008 16:27:09 -0000
@@ -953,9 +953,12 @@
       break;
 
     case DRUPAL_BOOTSTRAP_ACCESS:
-      // Deny access to hosts which were banned - t() is not yet available.
-      if (drupal_is_denied('host', ip_address())) {
+      // Deny access to hosts which were banned.
+      // Force at this point recalculation of the IP address
+      // overriding the possibly cached value.
+      if (drupal_is_denied('host', ip_address(TRUE))) {
         header('HTTP/1.1 403 Forbidden');
+        // t() is not yet available.
         print 'Sorry, '. check_plain(ip_address()) .' has been banned.';
         exit();
       }
@@ -1112,14 +1115,21 @@
  * If Drupal is behind a reverse proxy, we use the X-Forwarded-For header
  * instead of $_SERVER['REMOTE_ADDR'], which would be the IP address
  * of the proxy server, and not the client's.
+ * 
+ * With caching enabled, $ip_address will be available between requests.
+ * Behind a reverse proxy this would mean we are working with the client IP
+ * of an old request. Using the $reset flag once per request avoids this.
  *
+ * @param $reset
+ *   (optional) If TRUE, the IP address is reset and forcedly recalculated.
+ *   This should be used only once, at the very first call of a request.
  * @return
  *   IP address of client machine, adjusted for reverse proxy.
  */
-function ip_address() {
+function ip_address($reset=FALSE) {
   static $ip_address = NULL;
 
-  if (!isset($ip_address)) {
+  if (!isset($ip_address) || $reset) {
     $ip_address = $_SERVER['REMOTE_ADDR'];
     if (variable_get('reverse_proxy', 0) && array_key_exists('HTTP_X_FORWARDED_FOR', $_SERVER)) {
       // If an array of known reverse proxy IPs is provided, then trust
