X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=gateway.c;h=a8da953d5f357fbc6a868a63bc0faf0336e1050f;hp=0a98483216e0f185f26c67551c82cfacc182bd6b;hb=291f91036dabb40b2323a118dd34c368ae2c6848;hpb=8c3b1a6ae00b5609dfa74ae7c0c98981991ee05b diff --git a/gateway.c b/gateway.c index 0a984832..a8da953d 100644 --- a/gateway.c +++ b/gateway.c @@ -1,4 +1,4 @@ -const char gateway_rcs[] = "$Id: gateway.c,v 1.61 2009/09/10 14:59:34 fabiankeil Exp $"; +const char gateway_rcs[] = "$Id: gateway.c,v 1.72 2011/03/27 14:00:36 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/gateway.c,v $ @@ -7,7 +7,7 @@ const char gateway_rcs[] = "$Id: gateway.c,v 1.61 2009/09/10 14:59:34 fabiankeil * using a "forwarder" (i.e. HTTP proxy and/or a SOCKS4 * or SOCKS5 proxy). * - * Copyright : Written by and Copyright (C) 2001-2009 the SourceForge + * Copyright : Written by and Copyright (C) 2001-2009 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -88,21 +88,24 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, int target_port, struct client_state *csp); +enum { + SOCKS4_REQUEST_GRANTED = 90, + SOCKS4_REQUEST_REJECT = 91, + SOCKS4_REQUEST_IDENT_FAILED = 92, + SOCKS4_REQUEST_IDENT_CONFLICT = 93 +}; -#define SOCKS_REQUEST_GRANTED 90 -#define SOCKS_REQUEST_REJECT 91 -#define SOCKS_REQUEST_IDENT_FAILED 92 -#define SOCKS_REQUEST_IDENT_CONFLICT 93 - -#define SOCKS5_REQUEST_GRANTED 0 -#define SOCKS5_REQUEST_FAILED 1 -#define SOCKS5_REQUEST_DENIED 2 -#define SOCKS5_REQUEST_NETWORK_UNREACHABLE 3 -#define SOCKS5_REQUEST_HOST_UNREACHABLE 4 -#define SOCKS5_REQUEST_CONNECTION_REFUSED 5 -#define SOCKS5_REQUEST_TTL_EXPIRED 6 -#define SOCKS5_REQUEST_PROTOCOL_ERROR 7 -#define SOCKS5_REQUEST_BAD_ADDRESS_TYPE 8 +enum { + SOCKS5_REQUEST_GRANTED = 0, + SOCKS5_REQUEST_FAILED = 1, + SOCKS5_REQUEST_DENIED = 2, + SOCKS5_REQUEST_NETWORK_UNREACHABLE = 3, + SOCKS5_REQUEST_HOST_UNREACHABLE = 4, + SOCKS5_REQUEST_CONNECTION_REFUSED = 5, + SOCKS5_REQUEST_TTL_EXPIRED = 6, + SOCKS5_REQUEST_PROTOCOL_ERROR = 7, + SOCKS5_REQUEST_BAD_ADDRESS_TYPE = 8 +}; /* structure of a socks client operation */ struct socks_op { @@ -169,22 +172,20 @@ extern void initialize_reusable_connections(void) * * Function : remember_connection * - * Description : Remembers a connection for reuse later on. + * Description : Remembers a server connection for reuse later on. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : fwd = The forwarder settings used. + * 1 : connection = The server connection to remember. * * Returns : void * *********************************************************************/ -void remember_connection(const struct client_state *csp, const struct forward_spec *fwd) +void remember_connection(const struct reusable_connection *connection) { unsigned int slot = 0; int free_slot_found = FALSE; - const struct reusable_connection *connection = &csp->server_connection; - const struct http_request *http = csp->http; + assert(NULL != connection); assert(connection->sfd != JB_INVALID_SOCKET); if (mark_connection_unused(connection)) @@ -202,7 +203,7 @@ void remember_connection(const struct client_state *csp, const struct forward_sp assert(reusable_connection[slot].in_use == 0); log_error(LOG_LEVEL_CONNECT, "Remembering socket %d for %s:%d in slot %d.", - connection->sfd, http->host, http->port, slot); + connection->sfd, connection->host, connection->port, slot); free_slot_found = TRUE; break; } @@ -212,37 +213,36 @@ void remember_connection(const struct client_state *csp, const struct forward_sp { log_error(LOG_LEVEL_CONNECT, "No free slots found to remembering socket for %s:%d. Last slot %d.", - http->host, http->port, slot); + connection->host, connection->port, slot); privoxy_mutex_unlock(&connection_reuse_mutex); close_socket(connection->sfd); return; } - assert(NULL != http->host); - reusable_connection[slot].host = strdup(http->host); + assert(NULL != connection->host); + reusable_connection[slot].host = strdup(connection->host); if (NULL == reusable_connection[slot].host) { log_error(LOG_LEVEL_FATAL, "Out of memory saving socket."); } reusable_connection[slot].sfd = connection->sfd; - reusable_connection[slot].port = http->port; + reusable_connection[slot].port = connection->port; reusable_connection[slot].in_use = 0; reusable_connection[slot].timestamp = connection->timestamp; reusable_connection->request_sent = connection->request_sent; reusable_connection->response_received = connection->response_received; reusable_connection[slot].keep_alive_timeout = connection->keep_alive_timeout; - assert(NULL != fwd); assert(reusable_connection[slot].gateway_host == NULL); assert(reusable_connection[slot].gateway_port == 0); assert(reusable_connection[slot].forwarder_type == SOCKS_NONE); assert(reusable_connection[slot].forward_host == NULL); assert(reusable_connection[slot].forward_port == 0); - reusable_connection[slot].forwarder_type = fwd->type; - if (NULL != fwd->gateway_host) + reusable_connection[slot].forwarder_type = connection->forwarder_type; + if (NULL != connection->gateway_host) { - reusable_connection[slot].gateway_host = strdup(fwd->gateway_host); + reusable_connection[slot].gateway_host = strdup(connection->gateway_host); if (NULL == reusable_connection[slot].gateway_host) { log_error(LOG_LEVEL_FATAL, "Out of memory saving gateway_host."); @@ -252,11 +252,11 @@ void remember_connection(const struct client_state *csp, const struct forward_sp { reusable_connection[slot].gateway_host = NULL; } - reusable_connection[slot].gateway_port = fwd->gateway_port; + reusable_connection[slot].gateway_port = connection->gateway_port; - if (NULL != fwd->forward_host) + if (NULL != connection->forward_host) { - reusable_connection[slot].forward_host = strdup(fwd->forward_host); + reusable_connection[slot].forward_host = strdup(connection->forward_host); if (NULL == reusable_connection[slot].forward_host) { log_error(LOG_LEVEL_FATAL, "Out of memory saving forward_host."); @@ -266,7 +266,7 @@ void remember_connection(const struct client_state *csp, const struct forward_sp { reusable_connection[slot].forward_host = NULL; } - reusable_connection[slot].forward_port = fwd->forward_port; + reusable_connection[slot].forward_port = connection->forward_port; privoxy_mutex_unlock(&connection_reuse_mutex); } @@ -386,7 +386,9 @@ int connection_destination_matches(const struct reusable_connection *connection, && strcmpic(connection->gateway_host, fwd->gateway_host)) && (connection->gateway_host != fwd->gateway_host)) { - log_error(LOG_LEVEL_CONNECT, "Gateway mismatch."); + log_error(LOG_LEVEL_CONNECT, + "Gateway mismatch. Previous gateway: %s. Current gateway: %s", + connection->gateway_host, fwd->gateway_host); return FALSE; } @@ -395,7 +397,9 @@ int connection_destination_matches(const struct reusable_connection *connection, && strcmpic(connection->forward_host, fwd->forward_host)) && (connection->forward_host != fwd->forward_host)) { - log_error(LOG_LEVEL_CONNECT, "Forwarding proxy mismatch."); + log_error(LOG_LEVEL_CONNECT, + "Forwarding proxy mismatch. Previous proxy: %s. Current proxy: %s", + connection->forward_host, fwd->forward_host); return FALSE; } @@ -431,8 +435,8 @@ int close_unusable_connections(void) && (JB_INVALID_SOCKET != reusable_connection[slot].sfd)) { time_t time_open = time(NULL) - reusable_connection[slot].timestamp; - time_t latency = reusable_connection[slot].response_received - - reusable_connection[slot].request_sent; + time_t latency = (reusable_connection[slot].response_received - + reusable_connection[slot].request_sent) / 2; if (reusable_connection[slot].keep_alive_timeout < time_open + latency) { @@ -447,7 +451,7 @@ int close_unusable_connections(void) close_socket(reusable_connection[slot].sfd); mark_connection_closed(&reusable_connection[slot]); } - else if (!socket_is_still_usable(reusable_connection[slot].sfd)) + else if (!socket_is_still_alive(reusable_connection[slot].sfd)) { log_error(LOG_LEVEL_CONNECT, "The connection to %s:%d in slot %d is no longer usable. " @@ -805,12 +809,22 @@ static jb_socket socks4_connect(const struct forward_spec * fwd, if (sfd == JB_INVALID_SOCKET) { - /* - * XXX: connect_to should fill in the exact reason. - * Most likely resolving the IP of the forwarder failed. - */ - errstr = "connect_to failed: see logfile for details"; + /* The error an its reason have already been logged by connect_to() */ + return(JB_INVALID_SOCKET); + } + else if (!data_is_available(sfd, csp->config->socket_timeout)) + { + if (socket_is_still_alive(sfd)) + { + errstr = "SOCKS4 negotiation timed out"; + } + else + { + errstr = "SOCKS4 negotiation got aborted by the server"; + } + log_error(LOG_LEVEL_CONNECT, "socks4_connect: %s", errstr); err = 1; + close_socket(sfd); } else if (write_socket(sfd, (char *)c, csiz)) { @@ -835,18 +849,18 @@ static jb_socket socks4_connect(const struct forward_spec * fwd, switch (s->cd) { - case SOCKS_REQUEST_GRANTED: + case SOCKS4_REQUEST_GRANTED: return(sfd); - case SOCKS_REQUEST_REJECT: + case SOCKS4_REQUEST_REJECT: errstr = "SOCKS request rejected or failed."; errno = EINVAL; break; - case SOCKS_REQUEST_IDENT_FAILED: + case SOCKS4_REQUEST_IDENT_FAILED: errstr = "SOCKS request rejected because " "SOCKS server cannot connect to identd on the client."; errno = EACCES; break; - case SOCKS_REQUEST_IDENT_CONFLICT: + case SOCKS4_REQUEST_IDENT_CONFLICT: errstr = "SOCKS request rejected because " "the client program and identd report " "different user-ids."; @@ -1007,7 +1021,20 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, return(JB_INVALID_SOCKET); } - if (read_socket(sfd, sbuf, sizeof(sbuf)) != 2) + if (!data_is_available(sfd, csp->config->socket_timeout)) + { + if (socket_is_still_alive(sfd)) + { + errstr = "SOCKS5 negotiation timed out"; + } + else + { + errstr = "SOCKS5 negotiation got aborted by the server"; + } + err = 1; + } + + if (!err && read_socket(sfd, sbuf, sizeof(sbuf)) != 2) { errstr = "SOCKS5 negotiation read failed"; err = 1; @@ -1072,7 +1099,7 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, } else if (server_size > 20) { - /* This is somewhat unexpected but doesn't realy matter. */ + /* This is somewhat unexpected but doesn't really matter. */ log_error(LOG_LEVEL_CONNECT, "socks5_connect: read %d bytes " "from socks server. Would have accepted up to %d.", server_size, sizeof(sbuf));