X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=875c8a76575dbecf49a3737575f56bb2b3b325dc;hp=2f83e92f3f011b6a474db886bb0dae9973e1ab2e;hb=9126f0c935e4bb64a87be7c3a1855b7768791142;hpb=0edfbba21bc8791bca1d450b18b3ce4e0b7c3334 diff --git a/jcc.c b/jcc.c index 2f83e92f..875c8a76 100644 --- a/jcc.c +++ b/jcc.c @@ -90,11 +90,6 @@ #else #include #endif /* def __GLIBC__ */ -#else -# ifndef FD_ZERO -# include -# endif -#warning poll() appears to be unavailable. Your platform will become unsupported in the future. #endif /* HAVE_POLL */ #endif @@ -559,8 +554,6 @@ static int client_has_unsupported_expectations(const struct client_state *csp) *********************************************************************/ static jb_err get_request_destination_elsewhere(struct client_state *csp, struct list *headers) { - char *req; - if (!(csp->config->feature_flags & RUNTIME_FEATURE_ACCEPT_INTERCEPTED_REQUESTS)) { log_error(LOG_LEVEL_ERROR, "%s's request: \'%s\' is invalid." @@ -587,15 +580,12 @@ static jb_err get_request_destination_elsewhere(struct client_state *csp, struct { /* We can't work without destination. Go spread the news.*/ - req = list_to_text(headers); - chomp(req); /* XXX: Use correct size */ log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, csp->http->cmd); log_error(LOG_LEVEL_ERROR, - "Privoxy was unable to get the destination for %s's request:\n%s\n%s", - csp->ip_addr_str, csp->http->cmd, req); - freez(req); + "Privoxy was unable to get the destination for %s's request: %s", + csp->ip_addr_str, csp->http->cmd); write_socket_delayed(csp->cfd, MISSING_DESTINATION_RESPONSE, strlen(MISSING_DESTINATION_RESPONSE), get_write_delay(csp)); @@ -1176,6 +1166,22 @@ void save_connection_destination(jb_socket sfd, server_connection->gateway_host = NULL; } server_connection->gateway_port = fwd->gateway_port; + if (NULL != fwd->auth_username) + { + server_connection->auth_username = strdup_or_die(fwd->auth_username); + } + else + { + server_connection->auth_username = NULL; + } + if (NULL != fwd->auth_password) + { + server_connection->auth_password = strdup_or_die(fwd->auth_password); + } + else + { + server_connection->auth_password = NULL; + } if (NULL != fwd->forward_host) { @@ -2152,21 +2158,21 @@ static int send_https_request(struct client_state *csp) csp->http->hostport); return 1; } - if (flushed != 0) + if (flushed != 0 || csp->expected_client_content_length != 0) { if (csp->expected_client_content_length != 0) { if (csp->expected_client_content_length < flushed) { log_error(LOG_LEVEL_ERROR, - "Flushed %d bytes of request body while only expecting %llu", + "Flushed %ld bytes of request body while only expecting %llu", flushed, csp->expected_client_content_length); csp->expected_client_content_length = 0; } else { log_error(LOG_LEVEL_CONNECT, - "Flushed %d bytes of request body while expecting %llu", + "Flushed %ld bytes of request body while expecting %llu", flushed, csp->expected_client_content_length); csp->expected_client_content_length -= (unsigned)flushed; if (receive_and_send_encrypted_post_data(csp)) @@ -2178,7 +2184,7 @@ static int send_https_request(struct client_state *csp) else { log_error(LOG_LEVEL_CONNECT, - "Flushed %d bytes of request body", flushed); + "Flushed %ld bytes of request body", flushed); } } @@ -2276,7 +2282,8 @@ static jb_err process_encrypted_request(struct client_state *csp) err = receive_encrypted_request(csp); if (err != JB_ERR_OK) { - if (csp->client_iob->cur == NULL) + if (csp->client_iob->cur == NULL || + csp->client_iob->cur == csp->client_iob->eod) { /* * We did not receive any data, most likely because the @@ -2573,13 +2580,7 @@ static void handle_established_connection(struct client_state *csp) char *hdr; char *p; int n; -#ifdef HAVE_POLL struct pollfd poll_fds[2]; -#else - fd_set rfds; - jb_socket maxfd; - struct timeval timeout; -#endif int server_body; int ms_iis5_hack = 0; unsigned long long byte_count = 0; @@ -2618,11 +2619,6 @@ static void handle_established_connection(struct client_state *csp) http = csp->http; -#ifndef HAVE_POLL - maxfd = (csp->cfd > csp->server_connection.sfd) ? - csp->cfd : csp->server_connection.sfd; -#endif - /* pass data between the client and server * until one or the other shuts down the connection. */ @@ -2636,22 +2632,6 @@ static void handle_established_connection(struct client_state *csp) for (;;) { -#ifndef HAVE_POLL - FD_ZERO(&rfds); -#ifdef FEATURE_CONNECTION_KEEP_ALIVE - if (!watch_client_socket) - { - maxfd = csp->server_connection.sfd; - } - else -#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ - { - FD_SET(csp->cfd, &rfds); - } - - FD_SET(csp->server_connection.sfd, &rfds); -#endif /* ndef HAVE_POLL */ - #ifdef FEATURE_CONNECTION_KEEP_ALIVE if ((csp->flags & CSP_FLAG_CHUNKED) && !(csp->flags & CSP_FLAG_CONTENT_LENGTH_SET) @@ -2676,14 +2656,14 @@ static void handle_established_connection(struct client_state *csp) { log_error(LOG_LEVEL_CONNECT, "Done reading from server. Content length: %llu as expected. " - "Bytes most recently read: %d.", + "Bytes most recently read: %ld.", byte_count, len); } else { log_error(LOG_LEVEL_CONNECT, "Done reading from server. Expected content length: %llu. " - "Actual content length: %llu. Bytes most recently read: %d.", + "Actual content length: %llu. Bytes most recently read: %ld.", csp->expected_content_length, byte_count, len); } len = 0; @@ -2695,7 +2675,6 @@ static void handle_established_connection(struct client_state *csp) } #endif /* FEATURE_CONNECTION_KEEP_ALIVE */ -#ifdef HAVE_POLL poll_fds[0].fd = csp->cfd; #ifdef FEATURE_CONNECTION_KEEP_ALIVE if (!watch_client_socket) @@ -2716,11 +2695,6 @@ static void handle_established_connection(struct client_state *csp) poll_fds[1].fd = csp->server_connection.sfd; poll_fds[1].events = POLLIN; n = poll(poll_fds, 2, csp->config->socket_timeout * 1000); -#else - timeout.tv_sec = csp->config->socket_timeout; - timeout.tv_usec = 0; - n = select((int)maxfd + 1, &rfds, NULL, NULL, &timeout); -#endif /* def HAVE_POLL */ /*server or client not responding in timeout */ if (n == 0) @@ -2739,11 +2713,7 @@ static void handle_established_connection(struct client_state *csp) } else if (n < 0) { -#ifdef HAVE_POLL log_error(LOG_LEVEL_ERROR, "poll() failed!: %E"); -#else - log_error(LOG_LEVEL_ERROR, "select() failed!: %E"); -#endif mark_server_socket_tainted(csp); #ifdef FEATURE_HTTPS_INSPECTION close_client_and_server_ssl_connections(csp); @@ -2760,7 +2730,6 @@ static void handle_established_connection(struct client_state *csp) * XXX: Make sure the client doesn't use pipelining * behind Privoxy's back. */ -#ifdef HAVE_POLL if ((poll_fds[0].revents & (POLLERR|POLLHUP|POLLNVAL)) != 0) { log_error(LOG_LEVEL_CONNECT, @@ -2772,9 +2741,6 @@ static void handle_established_connection(struct client_state *csp) } if (poll_fds[0].revents != 0) -#else - if (FD_ISSET(csp->cfd, &rfds)) -#endif /* def HAVE_POLL*/ { int max_bytes_to_read = (int)csp->receive_buffer_size; @@ -2785,7 +2751,7 @@ static void handle_established_connection(struct client_state *csp) { /* * If the next request is already waiting, we have - * to stop select()ing the client socket. Otherwise + * to stop poll()ing the client socket. Otherwise * we would always return right away and get nothing * else done. */ @@ -2824,6 +2790,37 @@ static void handle_established_connection(struct client_state *csp) #ifdef FEATURE_HTTPS_INSPECTION if (client_use_ssl(csp)) { + if (csp->http->status == 101) + { + len = ssl_recv_data(&(csp->ssl_client_attr), + (unsigned char *)csp->receive_buffer, + (size_t)max_bytes_to_read); + if (len == -1) + { + log_error(LOG_LEVEL_ERROR, "Failed to receive data " + "on client socket %d for an upgraded connection", + csp->cfd); + break; + } + if (len == 0) + { + log_error(LOG_LEVEL_CONNECT, "Done receiving data " + "on client socket %d for an upgraded connection", + csp->cfd); + break; + } + byte_count += (unsigned long long)len; + len = ssl_send_data(&(csp->ssl_server_attr), + (unsigned char *)csp->receive_buffer, (size_t)len); + if (len == -1) + { + log_error(LOG_LEVEL_ERROR, "Failed to send data " + "on server socket %d for an upgraded connection", + csp->server_connection.sfd); + break; + } + continue; + } log_error(LOG_LEVEL_CONNECT, "Breaking with TLS/SSL."); break; } @@ -2846,7 +2843,7 @@ static void handle_established_connection(struct client_state *csp) csp->expected_client_content_length -= (unsigned)len; log_error(LOG_LEVEL_CONNECT, "Expected client content length set to %llu " - "after reading %d bytes.", + "after reading %ld bytes.", csp->expected_client_content_length, len); if (csp->expected_client_content_length == 0) { @@ -2872,11 +2869,7 @@ static void handle_established_connection(struct client_state *csp) * If `hdr' is null, then it's the header otherwise it's the body. * FIXME: Does `hdr' really mean `host'? No. */ -#ifdef HAVE_POLL if (poll_fds[1].revents != 0) -#else - if (FD_ISSET(csp->server_connection.sfd, &rfds)) -#endif /* HAVE_POLL */ { #ifdef FEATURE_CONNECTION_KEEP_ALIVE /* @@ -3320,7 +3313,7 @@ static void handle_established_connection(struct client_state *csp) */ log_error(LOG_LEVEL_CONNECT, "Continuing buffering server headers from socket %d. " - "Bytes most recently read: %d.", csp->cfd, len); + "Bytes most recently read: %ld.", csp->cfd, len); continue; } } @@ -4102,10 +4095,12 @@ static void chat(struct client_state *csp) else { /* - * If server certificate is invalid, we must inform client and then - * close connection with client. + * If server certificate has been verified and is invalid, + * we must inform the client and then close the connection + * with client and server. */ - if (csp->server_cert_verification_result != SSL_CERT_VALID) + if (csp->server_cert_verification_result != SSL_CERT_VALID && + csp->server_cert_verification_result != SSL_CERT_NOT_VERIFIED) { ssl_send_certificate_error(csp); close_client_and_server_ssl_connections(csp); @@ -4253,7 +4248,7 @@ static void prepare_csp_for_next_request(struct client_state *csp) assert(bytes_to_shift > 0); assert(data_length > 0); - log_error(LOG_LEVEL_CONNECT, "Shifting %d pipelined bytes by %d bytes", + log_error(LOG_LEVEL_CONNECT, "Shifting %lu pipelined bytes by %ld bytes", data_length, bytes_to_shift); memmove(csp->client_iob->buf, csp->client_iob->cur, data_length); csp->client_iob->cur = csp->client_iob->buf; @@ -4487,6 +4482,20 @@ static void serve(struct client_state *csp) chat(csp); #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ + if (csp->cfd != JB_INVALID_SOCKET) + { + log_error(LOG_LEVEL_CONNECT, "Closing client socket %d. " + "Keep-alive: %u. Socket alive: %u. Data available: %u. " + "Configuration file change detected: %u. Requests received: %u.", + csp->cfd, 0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE), + socket_is_still_alive(csp->cfd), data_is_available(csp->cfd, 0), + config_file_change_detected, csp->requests_received_total); +#ifdef FEATURE_HTTPS_INSPECTION + close_client_ssl_connection(csp); +#endif + drain_and_close_socket(csp->cfd); + } + if (csp->server_connection.sfd != JB_INVALID_SOCKET) { #ifdef FEATURE_CONNECTION_SHARING @@ -4507,20 +4516,6 @@ static void serve(struct client_state *csp) mark_connection_closed(&csp->server_connection); #endif - if (csp->cfd != JB_INVALID_SOCKET) - { - log_error(LOG_LEVEL_CONNECT, "Closing client socket %d. " - "Keep-alive: %u. Socket alive: %u. Data available: %u. " - "Configuration file change detected: %u. Requests received: %u.", - csp->cfd, 0 != (csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE), - socket_is_still_alive(csp->cfd), data_is_available(csp->cfd, 0), - config_file_change_detected, csp->requests_received_total); -#ifdef FEATURE_HTTPS_INSPECTION - close_client_ssl_connection(csp); -#endif - drain_and_close_socket(csp->cfd); - } - free_csp_resources(csp); csp->flags &= ~CSP_FLAG_ACTIVE; @@ -5304,17 +5299,6 @@ static jb_socket bind_port_helper(const char *haddr, int hport, int backlog) return JB_INVALID_SOCKET; } -#ifndef HAVE_POLL -#ifndef _WIN32 - if (bfd >= FD_SETSIZE) - { - log_error(LOG_LEVEL_FATAL, - "Bind socket number too high to use select(): %d >= %d", - bfd, FD_SETSIZE); - } -#endif -#endif - if (haddr == NULL) { log_error(LOG_LEVEL_INFO, "Listening on port %d on all IP addresses", @@ -5496,7 +5480,7 @@ static void listen_loop(void) csp = &csp_list->csp; log_error(LOG_LEVEL_CONNECT, - "Waiting for the next client connection. Currently active threads: %d", + "Waiting for the next client connection. Currently active threads: %u", active_threads); /* @@ -5713,7 +5697,7 @@ static void listen_loop(void) * XXX: If you assume ... */ log_error(LOG_LEVEL_ERROR, - "Unable to take any additional connections: %E. Active threads: %d", + "Unable to take any additional connections: %E. Active threads: %u", active_threads); write_socket_delayed(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE, strlen(TOO_MANY_CONNECTIONS_RESPONSE), get_write_delay(csp));