]> ruderich.org/simon Gitweb - tlsproxy/tlsproxy.git/commitdiff
src/connection.c: Close connections only in one place.
authorSimon Ruderich <simon@ruderich.org>
Mon, 7 Mar 2011 20:29:05 +0000 (21:29 +0100)
committerSimon Ruderich <simon@ruderich.org>
Mon, 7 Mar 2011 20:29:05 +0000 (21:29 +0100)
src/connection.c

index 982e23815e766eeedaf7673cef44fc85feff1baf..9a47ee1829389428c29691dec7c8e4a630f6e2cb 100644 (file)
@@ -57,8 +57,8 @@
 
 
 static int read_http_request(FILE *client_fd, char *request, size_t length);
-static void send_close_bad_request(FILE *client_fd);
-static void send_close_forwarding_failure(FILE *client_fd);
+static void send_bad_request(FILE *client_fd);
+static void send_forwarding_failure(FILE *client_fd);
 
 static void transfer_data(int client, int server);
 static int read_from_write_to(int from, int to);
@@ -84,30 +84,33 @@ void handle_connection(int client_socket) {
 
     LOG(LOG_DEBUG, "new connection");
 
+    server_socket = -1;
+    client_fd = NULL;
+    server_fd = NULL;
+
     client_fd = fdopen(client_socket, "a+");
     if (NULL == client_fd) {
         LOG_PERROR(LOG_WARNING, "fdopen(): client failed");
-        close(client_socket);
-        return;
+        goto out;
     }
 
     /* Read request line (CONNECT ..) and headers (they are discarded). */
     result = read_http_request(client_fd, buffer, sizeof(buffer));
     if (-1 == result) {
-        /* Read error, client_fd already closed. */
+        /* Read error. */
         LOG(LOG_WARNING, "read_http_request(): client read error");
-        return;
+        goto out;
     } else if (-2 == result) {
         /* EOF */
         LOG(LOG_WARNING, "read_http_request(): client EOF");
-        send_close_bad_request(client_fd);
-        return;
+        send_bad_request(client_fd);
+        goto out;
     }
 
     if (0 != parse_request(buffer, host, port, &version_minor)) {
         LOG(LOG_WARNING, "bad request: %s", buffer);
-        send_close_bad_request(client_fd);
-        return;
+        send_bad_request(client_fd);
+        goto out;
     }
 
     LOG(LOG_DEBUG, "target: %s:%s (HTTP 1.%d)", host, port, version_minor);
@@ -124,15 +127,14 @@ void handle_connection(int client_socket) {
 
     if (-1 == server_socket) {
         LOG(LOG_WARNING, "failed to connect to server");
-        send_close_forwarding_failure(client_fd);
-        return;
+        send_forwarding_failure(client_fd);
+        goto out;
     }
     server_fd = fdopen(server_socket, "a+");
     if (NULL == server_fd) {
         LOG_PERROR(LOG_WARNING, "fdopen(): server failed");
-        send_close_forwarding_failure(client_fd);
-        close(server_socket);
-        return;
+        send_forwarding_failure(client_fd);
+        goto out;
     }
 
     /* Connect to proxy if requested (command line option). */
@@ -143,24 +145,22 @@ void handle_connection(int client_socket) {
         /* Read response line from proxy server. */
         result = read_http_request(server_fd, buffer, sizeof(buffer));
         if (-1 == result) {
-            /* Read error, server_fd already closed. */
+            /* Read error. */
             LOG(LOG_WARNING, "read_http_request(): proxy read error");
-            send_close_forwarding_failure(client_fd);
-            return;
+            send_forwarding_failure(client_fd);
+            goto out;
         } else if (-2 == result) {
             /* EOF */
             LOG(LOG_WARNING, "read_http_request(): proxy EOF");
-            fclose(server_fd);
-            send_close_forwarding_failure(client_fd);
-            return;
+            send_forwarding_failure(client_fd);
+            goto out;
         }
 
         /* Check response of proxy server. */
         if (0 != strncmp(buffer, "HTTP/1.0 200", 12)) {
             LOG(LOG_WARNING, "bad proxy response: %s", buffer);
-            fclose(server_fd);
-            send_close_forwarding_failure(client_fd);
-            return;
+            send_forwarding_failure(client_fd);
+            goto out;
         }
     }
 
@@ -174,18 +174,28 @@ void handle_connection(int client_socket) {
     /* And transfer all data between client and server transparently. */
     transfer_data(client_socket, server_socket);
 
-    fclose(client_fd);
-    fclose(server_fd);
-
+out:
+    /* Close connection to server/proxy. */
+    if (NULL != server_fd) {
+        fclose(server_fd);
+    } else if (-1 != server_socket) {
+        close(server_socket);
+    }
     LOG(LOG_DEBUG, "connection to server closed");
+    /* Close connection to client. */
+    if (NULL != client_fd) {
+        fclose(client_fd);
+    } else {
+        close(client_socket);
+    }
+    LOG(LOG_DEBUG, "connection to client closed");
 
     LOG(LOG_DEBUG, "connection finished");
 }
 
 /* Read HTTP request line and headers (ignored).
  *
- * On success 0 is returned, -1 on client error (we close client descriptor in
- * this case), -2 on unexpected EOF.
+ * On success 0 is returned, -1 on client error, -2 on unexpected EOF.
  */
 static int read_http_request(FILE *client_fd, char *request, size_t length) {
     char buffer[MAX_REQUEST_LINE];
@@ -193,7 +203,6 @@ static int read_http_request(FILE *client_fd, char *request, size_t length) {
     if (NULL == fgets(request, (int)length, client_fd)) {
         if (ferror(client_fd)) {
             LOG_PERROR(LOG_WARNING, "read_http_request(): fgets()");
-            fclose(client_fd);
             return -1;
         }
 
@@ -208,22 +217,19 @@ static int read_http_request(FILE *client_fd, char *request, size_t length) {
     }
     if (ferror(client_fd)) {
         LOG_PERROR(LOG_WARNING, "read_http_request(): fgets()");
-        fclose(client_fd);
         return -1;
     }
 
     return 0;
 }
 
-static void send_close_bad_request(FILE *client_fd) {
+static void send_bad_request(FILE *client_fd) {
     fprintf(client_fd, "HTTP/1.0 400 Bad Request\r\n");
     fprintf(client_fd, "\r\n");
-    fclose(client_fd);
 }
-static void send_close_forwarding_failure(FILE *client_fd) {
+static void send_forwarding_failure(FILE *client_fd) {
     fprintf(client_fd, "HTTP/1.0 503 Forwarding failure\r\n");
     fprintf(client_fd, "\r\n");
-    fclose(client_fd);
 }