X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=gateway.c;h=c6b6db0eeb53249542f0f818bc60365a865ee36c;hp=0a77e0482472d0d59c3b89ff2773d29433501f5b;hb=87c40a0c37a9e9b067e94d0685901adde683b026;hpb=a9020a996f608a81d1f894e6c854c1e6edd485d7 diff --git a/gateway.c b/gateway.c index 0a77e048..c6b6db0e 100644 --- a/gateway.c +++ b/gateway.c @@ -1,4 +1,4 @@ -const char gateway_rcs[] = "$Id: gateway.c,v 1.62 2009/09/22 11:35:52 fabiankeil Exp $"; +const char gateway_rcs[] = "$Id: gateway.c,v 1.70 2011/02/19 13:55:57 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/gateway.c,v $ @@ -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; } @@ -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. " @@ -812,6 +816,20 @@ static jb_socket socks4_connect(const struct forward_spec * fwd, errstr = "connect_to failed: see logfile for details"; err = 1; } + 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)) { errstr = "SOCKS4 negotiation write failed."; @@ -835,18 +853,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 +1025,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;