X-Git-Url: http://www.privoxy.org/gitweb/?a=blobdiff_plain;f=gateway.c;h=f36ed01043657999375b7e1329b55a6f100ed2dc;hb=430b87b899c9294875101eee7faca82880a111e1;hp=933be51f31044e4bf6bfe75af8041a67be57b362;hpb=436cb74731fcfb84fd941598328d8d1c15f7a349;p=privoxy.git diff --git a/gateway.c b/gateway.c index 933be51f..f36ed010 100644 --- a/gateway.c +++ b/gateway.c @@ -1,4 +1,4 @@ -const char gateway_rcs[] = "$Id: gateway.c,v 1.69 2011/02/19 13:54:00 fabiankeil Exp $"; +const char gateway_rcs[] = "$Id: gateway.c,v 1.86 2012/03/09 17:55:50 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/gateway.c,v $ @@ -68,7 +68,7 @@ const char gateway_rcs[] = "$Id: gateway.c,v 1.69 2011/02/19 13:54:00 fabiankeil #include "miscutil.h" #ifdef FEATURE_CONNECTION_KEEP_ALIVE #ifdef HAVE_POLL -#ifdef __GLIBC__ +#ifdef __GLIBC__ #include #else #include @@ -88,11 +88,12 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, int target_port, struct client_state *csp); - -#define SOCKS4_REQUEST_GRANTED 90 -#define SOCKS4_REQUEST_REJECT 91 -#define SOCKS4_REQUEST_IDENT_FAILED 92 -#define SOCKS4_REQUEST_IDENT_CONFLICT 93 +enum { + SOCKS4_REQUEST_GRANTED = 90, + SOCKS4_REQUEST_REJECT = 91, + SOCKS4_REQUEST_IDENT_FAILED = 92, + SOCKS4_REQUEST_IDENT_CONFLICT = 93 +}; enum { SOCKS5_REQUEST_GRANTED = 0, @@ -337,16 +338,12 @@ void forget_connection(jb_socket sfd) sfd, reusable_connection[slot].host, reusable_connection[slot].port, slot); mark_connection_closed(&reusable_connection[slot]); - privoxy_mutex_unlock(&connection_reuse_mutex); - - return; + break; } } - log_error(LOG_LEVEL_CONNECT, - "Socket %d already forgotten or never remembered.", sfd); - privoxy_mutex_unlock(&connection_reuse_mutex); + } #endif /* def FEATURE_CONNECTION_SHARING */ @@ -658,7 +655,7 @@ jb_socket forwarded_connect(const struct forward_spec * fwd, default: /* Should never get here */ log_error(LOG_LEVEL_FATAL, - "SOCKS4 impossible internal error - bad SOCKS type."); + "Internal error in forwarded_connect(). Bad proxy type: %d", fwd->type); } if (JB_INVALID_SOCKET != sfd) @@ -727,7 +724,7 @@ static jb_socket socks4_connect(const struct forward_spec * fwd, if (err) { log_error(LOG_LEVEL_CONNECT, "socks4_connect: %s", errstr); - csp->error_message = strdup(errstr); + csp->error_message = strdup(errstr); errno = EINVAL; return(JB_INVALID_SOCKET); } @@ -796,24 +793,27 @@ static jb_socket socks4_connect(const struct forward_spec * fwd, c->vn = 4; c->cd = 1; - c->dstport[0] = (unsigned char)((target_port >> 8 ) & 0xff); - c->dstport[1] = (unsigned char)((target_port ) & 0xff); - c->dstip[0] = (unsigned char)((web_server_addr >> 24 ) & 0xff); - c->dstip[1] = (unsigned char)((web_server_addr >> 16 ) & 0xff); - c->dstip[2] = (unsigned char)((web_server_addr >> 8 ) & 0xff); - c->dstip[3] = (unsigned char)((web_server_addr ) & 0xff); + c->dstport[0] = (unsigned char)((target_port >> 8 ) & 0xff); + c->dstport[1] = (unsigned char)((target_port ) & 0xff); + c->dstip[0] = (unsigned char)((web_server_addr >> 24) & 0xff); + c->dstip[1] = (unsigned char)((web_server_addr >> 16) & 0xff); + c->dstip[2] = (unsigned char)((web_server_addr >> 8) & 0xff); + c->dstip[3] = (unsigned char)((web_server_addr ) & 0xff); /* pass the request to the socks server */ sfd = connect_to(fwd->gateway_host, fwd->gateway_port, csp); 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 (write_socket(sfd, (char *)c, csiz)) + { + errstr = "SOCKS4 negotiation write failed."; + log_error(LOG_LEVEL_CONNECT, "socks4_connect: %s", errstr); err = 1; + close_socket(sfd); } else if (!data_is_available(sfd, csp->config->socket_timeout)) { @@ -829,13 +829,6 @@ static jb_socket socks4_connect(const struct forward_spec * fwd, err = 1; close_socket(sfd); } - else if (write_socket(sfd, (char *)c, csiz)) - { - errstr = "SOCKS4 negotiation write failed."; - log_error(LOG_LEVEL_CONNECT, "socks4_connect: %s", errstr); - err = 1; - close_socket(sfd); - } else if (read_socket(sfd, buf, sizeof(buf)) != sizeof(*s)) { errstr = "SOCKS4 negotiation read failed."; @@ -846,7 +839,7 @@ static jb_socket socks4_connect(const struct forward_spec * fwd, if (err) { - csp->error_message = strdup(errstr); + csp->error_message = strdup(errstr); return(JB_INVALID_SOCKET); } @@ -950,7 +943,7 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, { int err = 0; char cbuf[300]; - char sbuf[30]; + char sbuf[10]; size_t client_pos = 0; int server_size = 0; size_t hostlen = 0; @@ -1006,6 +999,8 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, { errstr = "socks5 server unreachable"; log_error(LOG_LEVEL_CONNECT, "socks5_connect: %s", errstr); + /* Free the generic error message provided by connect_to() */ + freez(csp->error_message); csp->error_message = strdup(errstr); return(JB_INVALID_SOCKET); } @@ -1086,7 +1081,7 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, if (write_socket(sfd, cbuf, client_pos)) { - errstr = "SOCKS5 negotiation read failed"; + errstr = "SOCKS5 negotiation write failed"; csp->error_message = strdup(errstr); log_error(LOG_LEVEL_CONNECT, "%s", errstr); close_socket(sfd); @@ -1095,38 +1090,28 @@ static jb_socket socks5_connect(const struct forward_spec *fwd, } server_size = read_socket(sfd, sbuf, sizeof(sbuf)); - if (server_size < 3) + if (server_size != sizeof(sbuf)) { errstr = "SOCKS5 negotiation read failed"; - err = 1; } - else if (server_size > 20) - { - /* This is somewhat unexpected but doesn't realy matter. */ - log_error(LOG_LEVEL_CONNECT, "socks5_connect: read %d bytes " - "from socks server. Would have accepted up to %d.", - server_size, sizeof(sbuf)); - } - - if (!err && (sbuf[0] != '\x05')) - { - errstr = "SOCKS5 negotiation protocol version error"; - err = 1; - } - - if (!err && (sbuf[2] != '\x00')) - { - errstr = "SOCKS5 negotiation protocol error"; - err = 1; - } - - if (!err) + else { - if (sbuf[1] == SOCKS5_REQUEST_GRANTED) + if (sbuf[0] != '\x05') + { + errstr = "SOCKS5 negotiation protocol version error"; + } + else if (sbuf[2] != '\x00') + { + errstr = "SOCKS5 negotiation protocol error"; + } + else if (sbuf[1] != SOCKS5_REQUEST_GRANTED) + { + errstr = translate_socks5_error(sbuf[1]); + } + else { return(sfd); } - errstr = translate_socks5_error(sbuf[1]); } assert(errstr != NULL);