Commit df13f8e8 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

bits.close: introduce connection close tracking

Make all code use connclose() and connkeep() when changing the "close
state" for a connection. These two macros take a string argument with an
explanation, and debug builds of curl will include that in the debug
output. Helps tracking connection re-use/close issues.
parent 49176741
Loading
Loading
Loading
Loading
+2 −2
Original line number Original line Diff line number Diff line
@@ -5,7 +5,7 @@
 *                            | (__| |_| |  _ <| |___
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *                             \___|\___/|_| \_\_____|
 *
 *
 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 *
 * This software is licensed as described in the file COPYING, which
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * you should have received as part of this distribution. The terms
@@ -421,7 +421,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
       cleaning up this connection properly.
       cleaning up this connection properly.
       TODO: remove this action from here, it is not a name resolver decision.
       TODO: remove this action from here, it is not a name resolver decision.
    */
    */
    conn->bits.close = TRUE;
    connclose(conn, "c-ares resolve failed");


  return rc;
  return rc;
}
}
+1 −1
Original line number Original line Diff line number Diff line
@@ -446,7 +446,7 @@ CURLcode Curl_resolver_wait_resolv(struct connectdata *conn,
  destroy_async_data(&conn->async);
  destroy_async_data(&conn->async);


  if(!conn->async.dns)
  if(!conn->async.dns)
    conn->bits.close = TRUE;
    connclose(conn, "asynch resolve failed");


  return (rc);
  return (rc);
}
}
+17 −0
Original line number Original line Diff line number Diff line
@@ -1321,3 +1321,20 @@ CURLcode Curl_socket(struct connectdata *conn,
  return CURLE_OK;
  return CURLE_OK;


}
}

#ifdef CURLDEBUG
/*
 * Curl_conncontrol() is used to set the conn->bits.close bit on or off. It
 * MUST be called with the connclose() or connclose() macros with a stated
 * reason. The reason is only shown in debug builds but helps to figure out
 * decision paths when connections are or aren't re-used as expected.
 */
void Curl_conncontrol(struct connectdata *conn, bool closeit,
                      const char *reason)
{
  infof(conn->data, "Marked for [%s]: %s\n", closeit?"closure":"keep alive",
        reason);
  conn->bits.close = closeit; /* the only place in the source code that should
                                 assign this bit */
}
#endif
+18 −1
Original line number Original line Diff line number Diff line
@@ -7,7 +7,7 @@
 *                            | (__| |_| |  _ <| |___
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *                             \___|\___/|_| \_\_____|
 *
 *
 * Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 *
 * This software is licensed as described in the file COPYING, which
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * you should have received as part of this distribution. The terms
@@ -102,4 +102,21 @@ CURLcode Curl_socket(struct connectdata *conn,
                     struct Curl_sockaddr_ex *addr,
                     struct Curl_sockaddr_ex *addr,
                     curl_socket_t *sockfd);
                     curl_socket_t *sockfd);


#ifdef CURLDEBUG
/*
 * Curl_connclose() sets the bit.close bit to TRUE with an explanation.
 * Nothing else.
 */
void Curl_conncontrol(struct connectdata *conn,
                      bool closeit,
                      const char *reason);
#define connclose(x,y) Curl_conncontrol(x,TRUE, y)
#define connkeep(x,y) Curl_conncontrol(x, FALSE, y)
#else /* if !CURLDEBUG */

#define connclose(x,y) (x)->bits.close = TRUE
#define connkeep(x,y) (x)->bits.close = FALSE

#endif

#endif /* HEADER_CURL_CONNECT_H */
#endif /* HEADER_CURL_CONNECT_H */
+7 −7
Original line number Original line Diff line number Diff line
@@ -3164,7 +3164,7 @@ static CURLcode ftp_connect(struct connectdata *conn,
  *done = FALSE; /* default to not done yet */
  *done = FALSE; /* default to not done yet */


  /* We always support persistent connections on ftp */
  /* We always support persistent connections on ftp */
  conn->bits.close = FALSE;
  connkeep(conn, "FTP default");


  pp->response_time = RESP_TIMEOUT; /* set default response time-out */
  pp->response_time = RESP_TIMEOUT; /* set default response time-out */
  pp->statemach_act = ftp_statemach_act;
  pp->statemach_act = ftp_statemach_act;
@@ -3248,7 +3248,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
    ftpc->ctl_valid = FALSE;
    ftpc->ctl_valid = FALSE;
    ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the
    ftpc->cwdfail = TRUE; /* set this TRUE to prevent us to remember the
                             current path, as this connection is going */
                             current path, as this connection is going */
    conn->bits.close = TRUE; /* marked for closure */
    connclose(conn, "FTP ended with bad error code");
    result = status;      /* use the already set error code */
    result = status;      /* use the already set error code */
    break;
    break;
  }
  }
@@ -3272,7 +3272,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
    if(!result)
    if(!result)
      result = CURLE_OUT_OF_MEMORY;
      result = CURLE_OUT_OF_MEMORY;
    ftpc->ctl_valid = FALSE; /* mark control connection as bad */
    ftpc->ctl_valid = FALSE; /* mark control connection as bad */
    conn->bits.close = TRUE; /* mark for connection closure */
    connclose(conn, "FTP: out of memory!"); /* mark for connection closure */
    ftpc->prevpath = NULL; /* no path remembering */
    ftpc->prevpath = NULL; /* no path remembering */
  }
  }
  else {
  else {
@@ -3315,7 +3315,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
        failf(data, "Failure sending ABOR command: %s",
        failf(data, "Failure sending ABOR command: %s",
              curl_easy_strerror(result));
              curl_easy_strerror(result));
        ftpc->ctl_valid = FALSE; /* mark control connection as bad */
        ftpc->ctl_valid = FALSE; /* mark control connection as bad */
        conn->bits.close = TRUE; /* mark for connection closure */
        connclose(conn, "ABOR command failed"); /* connection closure */
      }
      }
    }
    }


@@ -3354,7 +3354,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
    if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
    if(!nread && (CURLE_OPERATION_TIMEDOUT == result)) {
      failf(data, "control connection looks dead");
      failf(data, "control connection looks dead");
      ftpc->ctl_valid = FALSE; /* mark control connection as bad */
      ftpc->ctl_valid = FALSE; /* mark control connection as bad */
      conn->bits.close = TRUE; /* mark for closure */
      connclose(conn, "Timeout or similar in FTP DONE operation"); /* close */
    }
    }


    if(result)
    if(result)
@@ -3364,7 +3364,7 @@ static CURLcode ftp_done(struct connectdata *conn, CURLcode status,
      /* we have just sent ABOR and there is no reliable way to check if it was
      /* we have just sent ABOR and there is no reliable way to check if it was
       * successful or not; we have to close the connection now */
       * successful or not; we have to close the connection now */
      infof(data, "partial download completed, closing connection\n");
      infof(data, "partial download completed, closing connection\n");
      conn->bits.close = TRUE; /* mark for closure */
      connclose(conn, "Partial download with no ability to check");
      return result;
      return result;
    }
    }


@@ -4133,7 +4133,7 @@ static CURLcode ftp_quit(struct connectdata *conn)
      failf(conn->data, "Failure sending QUIT command: %s",
      failf(conn->data, "Failure sending QUIT command: %s",
            curl_easy_strerror(result));
            curl_easy_strerror(result));
      conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
      conn->proto.ftpc.ctl_valid = FALSE; /* mark control connection as bad */
      conn->bits.close = TRUE; /* mark for connection closure */
      connclose(conn, "QUIT command failed"); /* mark for connection closure */
      state(conn, FTP_STOP);
      state(conn, FTP_STOP);
      return result;
      return result;
    }
    }
Loading