/*
- * $Id: tunnel.cc,v 1.168 2007/04/30 16:56:09 wessels Exp $
+ * $Id: tunnel.cc,v 1.169 2007/06/02 11:50:32 hno Exp $
*
* DEBUG: section 26 Secure Sockets Layer Proxy
* AUTHOR: Duane Wessels
static const char *const conn_established = "HTTP/1.0 200 Connection established\r\n\r\n";
-static CNCB sslConnectDone;
-static ERCB sslErrorComplete;
-static PF sslServerClosed;
-static PF sslClientClosed;
-static PF sslTimeout;
-static PSC sslPeerSelectComplete;
-static void sslStateFree(SslStateData * sslState);
-static void sslConnected(int fd, void *);
-static void sslProxyConnected(int fd, void *);
+static CNCB tunnelConnectDone;
+static ERCB tunnelErrorComplete;
+static PF tunnelServerClosed;
+static PF tunnelClientClosed;
+static PF tunnelTimeout;
+static PSC tunnelPeerSelectComplete;
+static void tunnelStateFree(SslStateData * tunnelState);
+static void tunnelConnected(int fd, void *);
+static void tunnelProxyConnected(int fd, void *);
static void
-sslServerClosed(int fd, void *data)
+tunnelServerClosed(int fd, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
- debugs(26, 3, "sslServerClosed: FD " << fd);
- assert(fd == sslState->server.fd());
- sslState->server.fd(-1);
+ SslStateData *tunnelState = (SslStateData *)data;
+ debugs(26, 3, "tunnelServerClosed: FD " << fd);
+ assert(fd == tunnelState->server.fd());
+ tunnelState->server.fd(-1);
- if (sslState->noConnections())
- sslStateFree(sslState);
+ if (tunnelState->noConnections())
+ tunnelStateFree(tunnelState);
}
static void
-sslClientClosed(int fd, void *data)
+tunnelClientClosed(int fd, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
- debugs(26, 3, "sslClientClosed: FD " << fd);
- assert(fd == sslState->client.fd());
- sslState->client.fd(-1);
+ SslStateData *tunnelState = (SslStateData *)data;
+ debugs(26, 3, "tunnelClientClosed: FD " << fd);
+ assert(fd == tunnelState->client.fd());
+ tunnelState->client.fd(-1);
- if (sslState->noConnections())
- sslStateFree(sslState);
+ if (tunnelState->noConnections())
+ tunnelStateFree(tunnelState);
}
static void
-sslStateFree(SslStateData * sslState)
+tunnelStateFree(SslStateData * tunnelState)
{
- debugs(26, 3, "sslStateFree: sslState=" << sslState);
- assert(sslState != NULL);
- assert(sslState->noConnections());
- safe_free(sslState->url);
- FwdState::serversFree(&sslState->servers);
- sslState->host = NULL;
- HTTPMSGUNLOCK(sslState->request);
- delete sslState;
+ debugs(26, 3, "tunnelStateFree: tunnelState=" << tunnelState);
+ assert(tunnelState != NULL);
+ assert(tunnelState->noConnections());
+ safe_free(tunnelState->url);
+ FwdState::serversFree(&tunnelState->servers);
+ tunnelState->host = NULL;
+ HTTPMSGUNLOCK(tunnelState->request);
+ delete tunnelState;
}
SslStateData::Connection::~Connection()
void
SslStateData::ReadServer(int fd, char *buf, size_t len, comm_err_t errcode, int xerrno, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
- assert (cbdataReferenceValid (sslState));
+ SslStateData *tunnelState = (SslStateData *)data;
+ assert (cbdataReferenceValid (tunnelState));
- assert(fd == sslState->server.fd());
- sslState->readServer(buf, len, errcode, xerrno);
+ assert(fd == tunnelState->server.fd());
+ tunnelState->readServer(buf, len, errcode, xerrno);
}
void
if (errcode == COMM_ERR_CLOSING)
return;
- debugs(26, 3, "sslReadServer: FD " << server.fd() << ", read " << len << " bytes");
+ debugs(26, 3, "tunnelReadServer: FD " << server.fd() << ", read " << len << " bytes");
if (len > 0) {
server.bytesIn(len);
if (xerrno == COMM_ERR_CLOSING)
return;
- debugs(50, debugLevelForError(xerrno), "sslReadServer: FD " << fd() <<
+ debugs(50, debugLevelForError(xerrno), "tunnelReadServer: FD " << fd() <<
": read failure: " << xstrerror());
if (!ignoreErrno(xerrno))
void
SslStateData::ReadClient(int fd, char *buf, size_t len, comm_err_t errcode, int xerrno, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
- assert (cbdataReferenceValid (sslState));
+ SslStateData *tunnelState = (SslStateData *)data;
+ assert (cbdataReferenceValid (tunnelState));
- assert(fd == sslState->client.fd());
- sslState->readClient(buf, len, errcode, xerrno);
+ assert(fd == tunnelState->client.fd());
+ tunnelState->readClient(buf, len, errcode, xerrno);
}
void
if (errcode == COMM_ERR_CLOSING)
return;
- debugs(26, 3, "sslReadClient: FD " << client.fd() << ", read " << len << " bytes");
+ debugs(26, 3, "tunnelReadClient: FD " << client.fd() << ", read " << len << " bytes");
if (len > 0) {
client.bytesIn(len);
void
SslStateData::WriteServerDone(int fd, char *buf, size_t len, comm_err_t flag, int xerrno, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
- assert (cbdataReferenceValid (sslState));
+ SslStateData *tunnelState = (SslStateData *)data;
+ assert (cbdataReferenceValid (tunnelState));
- assert(fd == sslState->server.fd());
- sslState->writeServerDone(buf, len, flag, xerrno);
+ assert(fd == tunnelState->server.fd());
+ tunnelState->writeServerDone(buf, len, flag, xerrno);
}
void
SslStateData::writeServerDone(char *buf, size_t len, comm_err_t flag, int xerrno)
{
- debugs(26, 3, "sslWriteServer: FD " << server.fd() << ", " << len << " bytes written");
+ debugs(26, 3, "tunnelWriteServer: FD " << server.fd() << ", " << len << " bytes written");
/* Error? */
if (len < 0 || flag != COMM_OK) {
void
SslStateData::WriteClientDone(int fd, char *buf, size_t len, comm_err_t flag, int xerrno, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
- assert (cbdataReferenceValid (sslState));
+ SslStateData *tunnelState = (SslStateData *)data;
+ assert (cbdataReferenceValid (tunnelState));
- assert(fd == sslState->client.fd());
- sslState->writeClientDone(buf, len, flag, xerrno);
+ assert(fd == tunnelState->client.fd());
+ tunnelState->writeClientDone(buf, len, flag, xerrno);
}
void
void
SslStateData::writeClientDone(char *buf, size_t len, comm_err_t flag, int xerrno)
{
- debugs(26, 3, "sslWriteClient: FD " << client.fd() << ", " << len << " bytes written");
+ debugs(26, 3, "tunnelWriteClient: FD " << client.fd() << ", " << len << " bytes written");
/* Error? */
if (len < 0 || flag != COMM_OK) {
}
static void
-sslTimeout(int fd, void *data)
+tunnelTimeout(int fd, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
- debugs(26, 3, "sslTimeout: FD " << fd);
- /* Temporary lock to protect our own feets (comm_close -> sslClientClosed -> Free) */
- cbdataInternalLock(sslState);
+ SslStateData *tunnelState = (SslStateData *)data;
+ debugs(26, 3, "tunnelTimeout: FD " << fd);
+ /* Temporary lock to protect our own feets (comm_close -> tunnelClientClosed -> Free) */
+ cbdataInternalLock(tunnelState);
- sslState->client.closeIfOpen();
- sslState->server.closeIfOpen();
- cbdataInternalUnlock(sslState);
+ tunnelState->client.closeIfOpen();
+ tunnelState->server.closeIfOpen();
+ cbdataInternalUnlock(tunnelState);
}
void
}
static void
-sslConnectTimeout(int fd, void *data)
+tunnelConnectTimeout(int fd, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
- HttpRequest *request = sslState->request;
+ SslStateData *tunnelState = (SslStateData *)data;
+ HttpRequest *request = tunnelState->request;
ErrorState *err = NULL;
- if (sslState->servers->_peer)
- hierarchyNote(&sslState->request->hier, sslState->servers->code,
- sslState->servers->_peer->host);
+ if (tunnelState->servers->_peer)
+ hierarchyNote(&tunnelState->request->hier, tunnelState->servers->code,
+ tunnelState->servers->_peer->host);
else if (Config.onoff.log_ip_on_direct)
- hierarchyNote(&sslState->request->hier, sslState->servers->code,
- fd_table[sslState->server.fd()].ipaddr);
+ hierarchyNote(&tunnelState->request->hier, tunnelState->servers->code,
+ fd_table[tunnelState->server.fd()].ipaddr);
else
- hierarchyNote(&sslState->request->hier, sslState->servers->code,
- sslState->host);
+ hierarchyNote(&tunnelState->request->hier, tunnelState->servers->code,
+ tunnelState->host);
comm_close(fd);
err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request);
- *sslState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
+ *tunnelState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
err->xerrno = ETIMEDOUT;
- err->port = sslState->port;
+ err->port = tunnelState->port;
- err->callback = sslErrorComplete;
+ err->callback = tunnelErrorComplete;
- err->callback_data = sslState;
+ err->callback_data = tunnelState;
- errorSend(sslState->client.fd(), err);
+ errorSend(tunnelState->client.fd(), err);
}
static void
-sslConnectedWriteDone(int fd, char *buf, size_t size, comm_err_t flag, int xerrno, void *data)
+tunnelConnectedWriteDone(int fd, char *buf, size_t size, comm_err_t flag, int xerrno, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
+ SslStateData *tunnelState = (SslStateData *)data;
if (flag != COMM_OK) {
- sslErrorComplete(fd, data, 0);
+ tunnelErrorComplete(fd, data, 0);
return;
}
- if (cbdataReferenceValid(sslState)) {
- sslState->copyRead(sslState->server, SslStateData::ReadServer);
- sslState->copyRead(sslState->client, SslStateData::ReadClient);
+ if (cbdataReferenceValid(tunnelState)) {
+ tunnelState->copyRead(tunnelState->server, SslStateData::ReadServer);
+ tunnelState->copyRead(tunnelState->client, SslStateData::ReadClient);
}
}
* handle the write completion from a proxy request to an upstream proxy
*/
static void
-sslProxyConnectedWriteDone(int fd, char *buf, size_t size, comm_err_t flag, int xerrno, void *data)
+tunnelProxyConnectedWriteDone(int fd, char *buf, size_t size, comm_err_t flag, int xerrno, void *data)
{
- sslConnectedWriteDone(fd, buf, size, flag, xerrno, data);
+ tunnelConnectedWriteDone(fd, buf, size, flag, xerrno, data);
}
static void
-sslConnected(int fd, void *data)
+tunnelConnected(int fd, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
- debugs(26, 3, "sslConnected: FD " << fd << " sslState=" << sslState);
- *sslState->status_ptr = HTTP_OK;
- comm_write(sslState->client.fd(), conn_established, strlen(conn_established),
- sslConnectedWriteDone, sslState, NULL);
+ SslStateData *tunnelState = (SslStateData *)data;
+ debugs(26, 3, "tunnelConnected: FD " << fd << " tunnelState=" << tunnelState);
+ *tunnelState->status_ptr = HTTP_OK;
+ comm_write(tunnelState->client.fd(), conn_established, strlen(conn_established),
+ tunnelConnectedWriteDone, tunnelState, NULL);
}
static void
-sslErrorComplete(int fdnotused, void *data, size_t sizenotused)
+tunnelErrorComplete(int fdnotused, void *data, size_t sizenotused)
{
- SslStateData *sslState = (SslStateData *)data;
- assert(sslState != NULL);
- /* temporary lock to save our own feets (comm_close -> sslClientClosed -> Free) */
- cbdataInternalLock(sslState);
+ SslStateData *tunnelState = (SslStateData *)data;
+ assert(tunnelState != NULL);
+ /* temporary lock to save our own feets (comm_close -> tunnelClientClosed -> Free) */
+ cbdataInternalLock(tunnelState);
- if (sslState->client.fd() > -1)
- comm_close(sslState->client.fd());
+ if (tunnelState->client.fd() > -1)
+ comm_close(tunnelState->client.fd());
- if (sslState->server.fd() > -1)
- comm_close(sslState->server.fd());
+ if (tunnelState->server.fd() > -1)
+ comm_close(tunnelState->server.fd());
- cbdataInternalUnlock(sslState);
+ cbdataInternalUnlock(tunnelState);
}
static void
-sslConnectDone(int fdnotused, comm_err_t status, int xerrno, void *data)
+tunnelConnectDone(int fdnotused, comm_err_t status, int xerrno, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
- HttpRequest *request = sslState->request;
+ SslStateData *tunnelState = (SslStateData *)data;
+ HttpRequest *request = tunnelState->request;
ErrorState *err = NULL;
- if (sslState->servers->_peer)
- hierarchyNote(&sslState->request->hier, sslState->servers->code,
- sslState->servers->_peer->host);
+ if (tunnelState->servers->_peer)
+ hierarchyNote(&tunnelState->request->hier, tunnelState->servers->code,
+ tunnelState->servers->_peer->host);
else if (Config.onoff.log_ip_on_direct)
- hierarchyNote(&sslState->request->hier, sslState->servers->code,
- fd_table[sslState->server.fd()].ipaddr);
+ hierarchyNote(&tunnelState->request->hier, tunnelState->servers->code,
+ fd_table[tunnelState->server.fd()].ipaddr);
else
- hierarchyNote(&sslState->request->hier, sslState->servers->code,
- sslState->host);
+ hierarchyNote(&tunnelState->request->hier, tunnelState->servers->code,
+ tunnelState->host);
if (status == COMM_ERR_DNS) {
- debugs(26, 4, "sslConnect: Unknown host: " << sslState->host);
+ debugs(26, 4, "tunnelConnect: Unknown host: " << tunnelState->host);
err = errorCon(ERR_DNS_FAIL, HTTP_NOT_FOUND, request);
- *sslState->status_ptr = HTTP_NOT_FOUND;
+ *tunnelState->status_ptr = HTTP_NOT_FOUND;
err->dnsserver_msg = xstrdup(dns_error_message);
- err->callback = sslErrorComplete;
- err->callback_data = sslState;
- errorSend(sslState->client.fd(), err);
+ err->callback = tunnelErrorComplete;
+ err->callback_data = tunnelState;
+ errorSend(tunnelState->client.fd(), err);
} else if (status != COMM_OK) {
err = errorCon(ERR_CONNECT_FAIL, HTTP_SERVICE_UNAVAILABLE, request);
- *sslState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
+ *tunnelState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
err->xerrno = xerrno;
- err->port = sslState->port;
- err->callback = sslErrorComplete;
- err->callback_data = sslState;
- errorSend(sslState->client.fd(), err);
+ err->port = tunnelState->port;
+ err->callback = tunnelErrorComplete;
+ err->callback_data = tunnelState;
+ errorSend(tunnelState->client.fd(), err);
} else {
- if (sslState->servers->_peer)
- sslProxyConnected(sslState->server.fd(), sslState);
+ if (tunnelState->servers->_peer)
+ tunnelProxyConnected(tunnelState->server.fd(), tunnelState);
else {
- sslConnected(sslState->server.fd(), sslState);
+ tunnelConnected(tunnelState->server.fd(), tunnelState);
}
- commSetTimeout(sslState->server.fd(),
+ commSetTimeout(tunnelState->server.fd(),
Config.Timeout.read,
- sslTimeout,
- sslState);
+ tunnelTimeout,
+ tunnelState);
}
}
void
-sslStart(ClientHttpRequest * http, size_t * size_ptr, int *status_ptr)
+tunnelStart(ClientHttpRequest * http, size_t * size_ptr, int *status_ptr)
{
/* Create state structure. */
- SslStateData *sslState = NULL;
+ SslStateData *tunnelState = NULL;
int sock;
ErrorState *err = NULL;
int answer;
}
}
- debugs(26, 3, "sslStart: '" << RequestMethodStr[request->method] << " " << url << "'");
+ debugs(26, 3, "tunnelStart: '" << RequestMethodStr[request->method] << " " << url << "'");
statCounter.server.all.requests++;
statCounter.server.other.requests++;
/* Create socket. */
url);
if (sock == COMM_ERROR) {
- debugs(26, 4, "sslStart: Failed because we're out of sockets.");
+ debugs(26, 4, "tunnelStart: Failed because we're out of sockets.");
err = errorCon(ERR_SOCKET_FAILURE, HTTP_INTERNAL_SERVER_ERROR, request);
*status_ptr = HTTP_INTERNAL_SERVER_ERROR;
err->xerrno = errno;
return;
}
- sslState = new SslStateData;
+ tunnelState = new SslStateData;
#if DELAY_POOLS
- sslState->server.setDelayId(DelayId::DelayClient(http));
+ tunnelState->server.setDelayId(DelayId::DelayClient(http));
#endif
- sslState->url = xstrdup(url);
- sslState->request = HTTPMSGLOCK(request);
- sslState->server.size_ptr = size_ptr;
- sslState->status_ptr = status_ptr;
- sslState->client.fd(fd);
- sslState->server.fd(sock);
- comm_add_close_handler(sslState->server.fd(),
- sslServerClosed,
- sslState);
- comm_add_close_handler(sslState->client.fd(),
- sslClientClosed,
- sslState);
- commSetTimeout(sslState->client.fd(),
+ tunnelState->url = xstrdup(url);
+ tunnelState->request = HTTPMSGLOCK(request);
+ tunnelState->server.size_ptr = size_ptr;
+ tunnelState->status_ptr = status_ptr;
+ tunnelState->client.fd(fd);
+ tunnelState->server.fd(sock);
+ comm_add_close_handler(tunnelState->server.fd(),
+ tunnelServerClosed,
+ tunnelState);
+ comm_add_close_handler(tunnelState->client.fd(),
+ tunnelClientClosed,
+ tunnelState);
+ commSetTimeout(tunnelState->client.fd(),
Config.Timeout.lifetime,
- sslTimeout,
- sslState);
- commSetTimeout(sslState->server.fd(),
+ tunnelTimeout,
+ tunnelState);
+ commSetTimeout(tunnelState->server.fd(),
Config.Timeout.connect,
- sslConnectTimeout,
- sslState);
+ tunnelConnectTimeout,
+ tunnelState);
peerSelect(request,
NULL,
- sslPeerSelectComplete,
- sslState);
+ tunnelPeerSelectComplete,
+ tunnelState);
/*
* Disable the client read handler until peer selection is complete
* Take control away from client_side.c.
*/
- commSetSelect(sslState->client.fd(), COMM_SELECT_READ, NULL, NULL, 0);
+ commSetSelect(tunnelState->client.fd(), COMM_SELECT_READ, NULL, NULL, 0);
}
static void
-sslProxyConnected(int fd, void *data)
+tunnelProxyConnected(int fd, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
+ SslStateData *tunnelState = (SslStateData *)data;
HttpHeader hdr_out(hoRequest);
Packer p;
http_state_flags flags;
- debugs(26, 3, "sslProxyConnected: FD " << fd << " sslState=" << sslState);
+ debugs(26, 3, "tunnelProxyConnected: FD " << fd << " tunnelState=" << tunnelState);
memset(&flags, '\0', sizeof(flags));
- flags.proxying = sslState->request->flags.proxying;
+ flags.proxying = tunnelState->request->flags.proxying;
MemBuf mb;
mb.init();
- mb.Printf("CONNECT %s HTTP/1.0\r\n", sslState->url);
- HttpStateData::httpBuildRequestHeader(sslState->request,
- sslState->request,
+ mb.Printf("CONNECT %s HTTP/1.0\r\n", tunnelState->url);
+ HttpStateData::httpBuildRequestHeader(tunnelState->request,
+ tunnelState->request,
NULL, /* StoreEntry */
&hdr_out,
flags); /* flags */
packerClean(&p);
mb.append("\r\n", 2);
- comm_write_mbuf(sslState->server.fd(), &mb, sslProxyConnectedWriteDone, sslState);
- commSetTimeout(sslState->server.fd(), Config.Timeout.read, sslTimeout, sslState);
+ comm_write_mbuf(tunnelState->server.fd(), &mb, tunnelProxyConnectedWriteDone, tunnelState);
+ commSetTimeout(tunnelState->server.fd(), Config.Timeout.read, tunnelTimeout, tunnelState);
}
static void
-sslPeerSelectComplete(FwdServer * fs, void *data)
+tunnelPeerSelectComplete(FwdServer * fs, void *data)
{
- SslStateData *sslState = (SslStateData *)data;
- HttpRequest *request = sslState->request;
+ SslStateData *tunnelState = (SslStateData *)data;
+ HttpRequest *request = tunnelState->request;
peer *g = NULL;
if (fs == NULL) {
ErrorState *err;
err = errorCon(ERR_CANNOT_FORWARD, HTTP_SERVICE_UNAVAILABLE, request);
- *sslState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
- err->callback = sslErrorComplete;
- err->callback_data = sslState;
- errorSend(sslState->client.fd(), err);
+ *tunnelState->status_ptr = HTTP_SERVICE_UNAVAILABLE;
+ err->callback = tunnelErrorComplete;
+ err->callback_data = tunnelState;
+ errorSend(tunnelState->client.fd(), err);
return;
}
- sslState->servers = fs;
- sslState->host = fs->_peer ? fs->_peer->host : request->host;
+ tunnelState->servers = fs;
+ tunnelState->host = fs->_peer ? fs->_peer->host : request->host;
if (fs->_peer == NULL) {
- sslState->port = request->port;
+ tunnelState->port = request->port;
} else if (fs->_peer->http_port != 0) {
- sslState->port = fs->_peer->http_port;
+ tunnelState->port = fs->_peer->http_port;
} else if ((g = peerFindByName(fs->_peer->host))) {
- sslState->port = g->http_port;
+ tunnelState->port = g->http_port;
} else {
- sslState->port = CACHE_HTTP_PORT;
+ tunnelState->port = CACHE_HTTP_PORT;
}
if (fs->_peer) {
- sslState->request->peer_login = fs->_peer->login;
- sslState->request->flags.proxying = 1;
+ tunnelState->request->peer_login = fs->_peer->login;
+ tunnelState->request->flags.proxying = 1;
} else {
- sslState->request->peer_login = NULL;
- sslState->request->flags.proxying = 0;
+ tunnelState->request->peer_login = NULL;
+ tunnelState->request->flags.proxying = 0;
}
#if DELAY_POOLS
- /* no point using the delayIsNoDelay stuff since ssl is nice and simple */
+ /* no point using the delayIsNoDelay stuff since tunnel is nice and simple */
if (g && g->options.no_delay)
- sslState->server.setDelayId(DelayId());
+ tunnelState->server.setDelayId(DelayId());
#endif
- commConnectStart(sslState->server.fd(),
- sslState->host,
- sslState->port,
- sslConnectDone,
- sslState);
+ commConnectStart(tunnelState->server.fd(),
+ tunnelState->host,
+ tunnelState->port,
+ tunnelConnectDone,
+ tunnelState);
}
CBDATA_CLASS_INIT(SslStateData);