X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=20647fa708ee6c3b389555818331f3c95b8e117f;hp=c0d3cba7e53c2ab7eb9f9aff316e64820f2cfa7b;hb=54b4e8c141117d636f6113ec4c43579248b77ed7;hpb=f89cccf0ffd0b7f0ff484e2c6947aa0f2503118c diff --git a/jcc.c b/jcc.c index c0d3cba7..20647fa7 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.298 2009/10/04 15:34:17 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.310 2009/12/29 13:17:37 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -119,7 +119,7 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.298 2009/10/04 15:34:17 fabiankeil Exp $" const char jcc_h_rcs[] = JCC_H_VERSION; const char project_h_rcs[] = PROJECT_H_VERSION; -int no_daemon = 0; +int daemon_mode = 1; struct client_state clients[1]; struct file_list files[1]; @@ -724,19 +724,21 @@ static void send_crunch_response(const struct client_state *csp, struct http_res status_code[2] = rsp->head[11]; status_code[3] = '\0'; + /* Log that the request was crunched and why. */ + log_error(LOG_LEVEL_CRUNCH, "%s: %s", crunch_reason(rsp), http->url); + log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %u", + csp->ip_addr_str, http->ocmd, status_code, rsp->content_length); + /* Write the answer to the client */ if (write_socket(csp->cfd, rsp->head, rsp->head_length) || write_socket(csp->cfd, rsp->body, rsp->content_length)) { /* There is nothing we can do about it. */ - log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", csp->http->host); + log_error(LOG_LEVEL_ERROR, + "Couldn't deliver the error message through client socket %d: %E", + csp->cfd); } - /* Log that the request was crunched and why. */ - log_error(LOG_LEVEL_CRUNCH, "%s: %s", crunch_reason(rsp), http->url); - log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" %s %u", - csp->ip_addr_str, http->ocmd, status_code, rsp->content_length); - /* Clean up and return */ if (cgi_error_memory() != rsp) { @@ -1265,8 +1267,9 @@ static char *get_request_line(struct client_state *csp) { if (!data_is_available(csp->cfd, csp->config->socket_timeout)) { - log_error(LOG_LEVEL_ERROR, - "Stopped waiting for the request line."); + log_error(LOG_LEVEL_CONNECT, + "Stopped waiting for the request line. Timeout: %d.", + csp->config->socket_timeout); write_socket(csp->cfd, CLIENT_CONNECTION_TIMEOUT_RESPONSE, strlen(CLIENT_CONNECTION_TIMEOUT_RESPONSE)); return NULL; @@ -1602,7 +1605,9 @@ static void chat(struct client_state *csp) /* Skeleton for HTTP response, if we should intercept the request */ struct http_response *rsp; struct timeval timeout; +#ifdef FEATURE_CONNECTION_KEEP_ALIVE int watch_client_socket = 1; +#endif memset(buf, 0, sizeof(buf)); @@ -2513,33 +2518,37 @@ static void serve(struct client_state *csp) && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED) && (csp->cfd != JB_INVALID_SOCKET) && (csp->server_connection.sfd != JB_INVALID_SOCKET) - && socket_is_still_usable(csp->server_connection.sfd) - && (latency < csp->server_connection.keep_alive_timeout); + && socket_is_still_usable(csp->server_connection.sfd); if (continue_chatting) { - unsigned int client_timeout; - if (!(csp->flags & CSP_FLAG_SERVER_KEEP_ALIVE_TIMEOUT_SET)) { - log_error(LOG_LEVEL_CONNECT, "The server didn't specify how long " - "the connection will stay open. Assume it's only a second."); - csp->server_connection.keep_alive_timeout = 1; + csp->server_connection.keep_alive_timeout = csp->config->default_server_timeout; + log_error(LOG_LEVEL_CONNECT, + "The server didn't specify how long the connection will stay open. " + "Assumed timeout is: %u.", csp->server_connection.keep_alive_timeout); } + continue_chatting = (latency < csp->server_connection.keep_alive_timeout); + } + + if (continue_chatting) + { + unsigned int client_timeout; client_timeout = (unsigned)csp->server_connection.keep_alive_timeout - latency; log_error(LOG_LEVEL_CONNECT, - "Waiting for the next client request. " + "Waiting for the next client request on socket %d. " "Keeping the server socket %d to %s open.", - csp->server_connection.sfd, csp->server_connection.host); - + csp->cfd, csp->server_connection.sfd, csp->server_connection.host); if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE) && data_is_available(csp->cfd, (int)client_timeout) && socket_is_still_usable(csp->cfd)) { log_error(LOG_LEVEL_CONNECT, "Client request arrived in " - "time or the client closed the connection."); + "time or the client closed the connection on socket %d.", + csp->cfd); /* * Get the csp in a mostly vergin state again. * XXX: Should be done elsewhere. @@ -2569,7 +2578,8 @@ static void serve(struct client_state *csp) else { log_error(LOG_LEVEL_CONNECT, - "No additional client request received in time."); + "No additional client request received in time on socket %d.", + csp->cfd); #ifdef FEATURE_CONNECTION_SHARING if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING) && (socket_is_still_usable(csp->server_connection.sfd))) @@ -2608,7 +2618,6 @@ static void serve(struct client_state *csp) } } while (continue_chatting); - mark_connection_closed(&csp->server_connection); #else chat(csp); #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ @@ -2616,11 +2625,18 @@ static void serve(struct client_state *csp) if (csp->server_connection.sfd != JB_INVALID_SOCKET) { #ifdef FEATURE_CONNECTION_SHARING - forget_connection(csp->server_connection.sfd); + if (csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING) + { + forget_connection(csp->server_connection.sfd); + } #endif /* def FEATURE_CONNECTION_SHARING */ close_socket(csp->server_connection.sfd); } +#ifdef FEATURE_CONNECTION_KEEP_ALIVE + mark_connection_closed(&csp->server_connection); +#endif + if (csp->cfd != JB_INVALID_SOCKET) { close_socket(csp->cfd); @@ -2935,7 +2951,7 @@ int main(int argc, char **argv) else if (strcmp(argv[argc_pos], "--no-daemon" ) == 0) { set_debug_level(LOG_LEVEL_FATAL | LOG_LEVEL_ERROR | LOG_LEVEL_INFO); - no_daemon = 1; + daemon_mode = 0; } else if (strcmp(argv[argc_pos], "--pidfile" ) == 0) @@ -3102,12 +3118,11 @@ int main(int argc, char **argv) #if defined(unix) { pid_t pid = 0; -#if 0 - int fd; -#endif - if (!no_daemon) + if (daemon_mode) { + int fd; + pid = fork(); if ( pid < 0 ) /* error */ @@ -3132,33 +3147,50 @@ int main(int argc, char **argv) exit( 0 ); } /* child */ -#if 1 - /* Should be more portable, but not as well tested */ + setsid(); -#else /* !1 */ -#ifdef __FreeBSD__ - setpgrp(0,0); -#else /* ndef __FreeBSD__ */ - setpgrp(); -#endif /* ndef __FreeBSD__ */ - fd = open("/dev/tty", O_RDONLY); - if ( fd ) - { - /* no error check here */ - ioctl( fd, TIOCNOTTY,0 ); - close ( fd ); - } -#endif /* 1 */ + /* * stderr (fd 2) will be closed later on, * when the config file has been parsed. */ + close(0); + close(1); + + /* + * Reserve fd 0 and 1 to prevent abort() and friends + * from sending stuff to the clients or servers. + */ + fd = open("/dev/null", O_RDONLY); + if (fd == -1) + { + log_error(LOG_LEVEL_FATAL, "Failed to open /dev/null: %E"); + } + else if (fd != 0) + { + if (dup2(fd, 0) == -1) + { + log_error(LOG_LEVEL_FATAL, "Failed to reserve fd 0: %E"); + } + close(fd); + } + fd = open("/dev/null", O_WRONLY); + if (fd == -1) + { + log_error(LOG_LEVEL_FATAL, "Failed to open /dev/null: %E"); + } + else if (fd != 1) + { + if (dup2(fd, 1) == -1) + { + log_error(LOG_LEVEL_FATAL, "Failed to reserve fd 1: %E"); + } + close(fd); + } - close( 0 ); - close( 1 ); chdir("/"); - } /* -END- if (!no_daemon) */ + } /* -END- if (daemon_mode) */ /* * As soon as we have written the PID file, we can switch