* Purpose : Main file. Contains main() method, main loop, and
* the main connection-handling function.
*
- * Copyright : Written by and Copyright (C) 2001-2021 the
+ * Copyright : Written by and Copyright (C) 2001-2022 the
* Privoxy team. https://www.privoxy.org/
*
* Based on the Internet Junkbuster originally written
#ifdef FEATURE_STATISTICS
int urls_read = 0; /* total nr of urls read inc rejected */
int urls_rejected = 0; /* total nr of urls rejected */
+#ifdef MUTEX_LOCKS_AVAILABLE
+unsigned long long number_of_requests_received = 0;
+unsigned long long number_of_requests_blocked = 0;
+#endif
#endif /* def FEATURE_STATISTICS */
#ifdef FEATURE_GRACEFUL_TERMINATION
#ifdef FEATURE_CLIENT_TAGS
privoxy_mutex_t client_tags_mutex;
#endif
+#ifdef FEATURE_STATISTICS
+privoxy_mutex_t block_statistics_mutex;
+#endif
#ifdef FEATURE_EXTENDED_STATISTICS
privoxy_mutex_t filter_statistics_mutex;
-privoxy_mutex_t block_statistics_mutex;
+privoxy_mutex_t block_reason_statistics_mutex;
#endif
#if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_GETHOSTBYNAME_R)
#ifdef FEATURE_STATISTICS
if (c->flags & CF_COUNT_AS_REJECT)
{
+#ifdef MUTEX_LOCKS_AVAILABLE
+ privoxy_mutex_lock(&block_statistics_mutex);
+ number_of_requests_blocked++;
+ privoxy_mutex_unlock(&block_statistics_mutex);
+#endif
csp->flags |= CSP_FLAG_REJECTED;
}
#endif /* def FEATURE_STATISTICS */
free_http_request(http);
return JB_ERR_PARSE;
}
+ if (http->ssl && strcmpic(http->gpc, "CONNECT"))
+ {
+ write_socket_delayed(csp->cfd, CHEADER, strlen(CHEADER),
+ get_write_delay(csp));
+ /* XXX: Use correct size */
+ log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request\" 400 0",
+ csp->ip_addr_str);
+ log_error(LOG_LEVEL_ERROR, "Client %s tried to send a https "
+ "URL without sending a CONNECT request first",
+ csp->ip_addr_str);
+ free_http_request(http);
+ return JB_ERR_PARSE;
+ }
/* grab the rest of the client's headers */
init_list(headers);
if (!data_is_available(csp->cfd, csp->config->socket_timeout))
{
log_error(LOG_LEVEL_ERROR,
- "Stopped grabbing the client headers.");
+ "Client headers did not arrive in time. Timeout: %d",
+ csp->config->socket_timeout);
destroy_list(headers);
return JB_ERR_PARSE;
}
{
log_error(LOG_LEVEL_INFO,
"Not filtering request body from %s: buffer limit %lu will be exceeded "
- "(content length %lluu)", csp->ip_addr_str, csp->config->buffer_limit,
+ "(content length %llu)", csp->ip_addr_str, csp->config->buffer_limit,
csp->expected_client_content_length);
return FALSE;
}
size_t max_bytes_to_read = to_read < sizeof(buf) ? to_read : sizeof(buf);
log_error(LOG_LEVEL_CONNECT,
- "Waiting for up to %lu bytes of request body from the client.",
+ "Buffering encrypted client body. Prepared to read up to %lu bytes.",
max_bytes_to_read);
len = ssl_recv_data(&(csp->ssl_client_attr), buf,
(unsigned)max_bytes_to_read);
if (len <= 0)
{
- log_error(LOG_LEVEL_CONNECT, "Failed receiving request body from %s", csp->ip_addr_str);
+ log_error(LOG_LEVEL_CONNECT,
+ "Did not receive the whole encrypted request body from %s",
+ csp->ip_addr_str);
return 1;
}
if (add_to_iob(csp->client_iob, csp->config->buffer_limit, (char *)buf, len))
if (to_read != 0)
{
log_error(LOG_LEVEL_CONNECT,
- "Not enough request body has been read: expected %lu more bytes",
+ "Not enough encrypted request body has been read: expected %lu more bytes",
to_read);
return 1;
}
log_error(LOG_LEVEL_CONNECT,
- "The last %llu bytes of the request body have been read",
+ "The last %llu bytes of the encrypted request body have been read",
csp->expected_client_content_length);
return 0;
}
{
int content_length_known = csp->expected_client_content_length != 0;
- while (is_ssl_pending(&(csp->ssl_client_attr))
- || (content_length_known && csp->expected_client_content_length != 0))
+ while ((content_length_known && csp->expected_client_content_length != 0) ||
+ (is_ssl_pending(&(csp->ssl_client_attr)) ||
+ data_is_available(csp->cfd, csp->config->socket_timeout)))
{
unsigned char buf[BUFFER_SIZE];
int len;
max_bytes_to_read = (int)csp->expected_client_content_length;
}
log_error(LOG_LEVEL_CONNECT,
- "Waiting for up to %d bytes of request body from the client.",
+ "Prepared to read up to %d bytes of encrypted request body from the client.",
max_bytes_to_read);
len = ssl_recv_data(&(csp->ssl_client_attr), buf,
(unsigned)max_bytes_to_read);
return;
}
+#if defined(FEATURE_STATISTICS) && defined(MUTEX_LOCKS_AVAILABLE)
+ privoxy_mutex_lock(&block_statistics_mutex);
+ number_of_requests_received++;
+ privoxy_mutex_unlock(&block_statistics_mutex);
+#endif
+
csp->requests_received_total++;
/*
*/
goto server_wants_to_talk;
}
+ if (watch_client_socket && client_use_ssl(csp) &&
+ is_ssl_pending(&(csp->ssl_client_attr)))
+ {
+ /*
+ * The TLS libray may also consume all of the remaining data
+ * from the client when we're shuffling the data from an
+ * unbuffered request body to the server.
+ */
+ goto client_wants_to_talk;
+ }
#endif
#ifndef HAVE_POLL
FD_ZERO(&rfds);
if (FD_ISSET(csp->cfd, &rfds))
#endif /* def HAVE_POLL*/
{
- int max_bytes_to_read = (int)csp->receive_buffer_size;
+ int max_bytes_to_read;
+
+#ifdef FEATURE_HTTPS_INSPECTION
+ client_wants_to_talk:
+#endif
+
+ max_bytes_to_read = (int)csp->receive_buffer_size;
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
if ((csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ))
{
return;
}
+
+#if defined(FEATURE_STATISTICS) && defined(MUTEX_LOCKS_AVAILABLE)
+ privoxy_mutex_lock(&block_statistics_mutex);
+ number_of_requests_received++;
+ privoxy_mutex_unlock(&block_statistics_mutex);
+#endif
+
if (parse_client_request(csp) != JB_ERR_OK)
{
return;
#ifdef FEATURE_CLIENT_TAGS
privoxy_mutex_init(&client_tags_mutex);
#endif
+#ifdef FEATURE_STATISTICS
+ privoxy_mutex_init(&block_statistics_mutex);
+#endif
#ifdef FEATURE_EXTENDED_STATISTICS
privoxy_mutex_init(&filter_statistics_mutex);
- privoxy_mutex_init(&block_statistics_mutex);
+ privoxy_mutex_init(&block_reason_statistics_mutex);
#endif
/*