- Added support for retrying connect().
/*
- * $Id: comm.cc,v 1.155 1997/05/26 04:04:56 wessels Exp $
+ * $Id: comm.cc,v 1.156 1997/06/01 23:22:17 wessels Exp $
*
* DEBUG: section 5 Socket Functions
* AUTHOR: Harvest Derived
static void commConnectHandle _PARAMS((int fd, void *data));
static void commHandleWrite _PARAMS((int fd, void *data));
static int fdIsHttpOrIcp _PARAMS((int fd));
+static IPH commConnectDnsHandle;
static struct timeval zero_tv;
}
}
-
static void
CommWriteStateCallbackAndFree(int fd, int code)
{
cs->callback = callback;
cs->data = data;
comm_add_close_handler(fd, commConnectFree, cs);
+ ipcache_nbgethostbyname(host, fd, commConnectDnsHandle, cs);
+}
+
+static void
+commConnectDnsHandle(int fd, const ipcache_addrs * ia, void *data)
+{
+ ConnectStateData *cs = data;
+ if (ia == NULL) {
+ debug(5, 3, "commConnectDnsHandle: Unknown host: %s\n", cs->host);
+ cs->callback(fd, COMM_ERR_DNS, cs->data);
+ return;
+ }
+ cs->in_addr = ia->in_addrs[ia->cur];
commConnectHandle(fd, cs);
}
xfree(cs);
}
+static int
+commRetryConnect(int fd, ConnectStateData * connectState)
+{
+ int fd2;
+ if (++connectState->tries == 4)
+ return 0;
+ fd2 = socket(AF_INET, SOCK_STREAM, 0);
+ if (fd2 < 0) {
+ debug(5, 0, "commRetryConnect: socket: %s\n", xstrerror());
+ return 0;
+ }
+ if (dup2(fd2, fd) < 0) {
+ debug(5, 0, "commRetryConnect: dup2: %s\n", xstrerror());
+ return 0;
+ }
+ commSetNonBlocking(fd);
+ close(fd2);
+ return 1;
+}
+
/* Connect SOCK to specified DEST_PORT at DEST_HOST. */
static void
commConnectHandle(int fd, void *data)
{
ConnectStateData *connectState = data;
- const ipcache_addrs *ia = NULL;
if (connectState->S.sin_addr.s_addr == 0) {
- ia = ipcache_gethostbyname(connectState->host, IP_BLOCKING_LOOKUP);
- if (ia == NULL) {
- debug(5, 3, "commConnectHandle: Unknown host: %s\n",
- connectState->host);
- connectState->callback(fd,
- COMM_ERROR,
- connectState->data);
- return;
- }
connectState->S.sin_family = AF_INET;
- connectState->S.sin_addr = ia->in_addrs[ia->cur];
+ connectState->S.sin_addr = connectState->in_addr;
connectState->S.sin_port = htons(connectState->port);
if (Config.Log.log_fqdn)
fqdncache_gethostbyaddr(connectState->S.sin_addr, FQDN_LOOKUP_IF_MISS);
connectState->callback(fd, COMM_OK, connectState->data);
break;
default:
- ipcacheRemoveBadAddr(connectState->host, connectState->S.sin_addr);
- connectState->callback(fd, COMM_ERROR, connectState->data);
+ if (commRetryConnect(fd, connectState)) {
+ debug(5, 1, "Retrying connection to %s: %s\n",
+ connectState->host, xstrerror());
+ connectState->S.sin_addr.s_addr = 0;
+ ipcacheCycleAddr(connectState->host);
+ ipcache_nbgethostbyname(connectState->host,
+ fd,
+ commConnectDnsHandle,
+ connectState);
+ } else {
+ ipcacheRemoveBadAddr(connectState->host, connectState->S.sin_addr);
+ connectState->callback(fd, COMM_ERR_CONNECT, connectState->data);
+ }
break;
}
}
if (connect(sock, (struct sockaddr *) address, sizeof(struct sockaddr_in)) < 0) {
switch (errno) {
case EALREADY:
- return COMM_ERROR;
- /* NOTREACHED */
#if EAGAIN != EWOULDBLOCK
case EAGAIN:
#endif
return 0;
}
-int
-comm_join_mcast_groups(int fd)
+void
+comm_join_mcast_groups(int fd, const ipcache_addrs * ia, void *data)
{
#ifdef IP_MULTICAST_TTL
struct ip_mreq mr;
- wordlist *s = NULL;
- const ipcache_addrs *ia = NULL;
int i;
int x;
char c = 0;
- for (s = Config.mcast_group_list; s; s = s->next) {
- debug(5, 10, "comm_join_mcast_groups: joining group %s on FD %d\n",
- s->key, fd);
- ia = ipcache_gethostbyname(s->key, IP_BLOCKING_LOOKUP);
- if (ia == NULL) {
- debug(5, 0, "Unknown host: %s\n", s->key);
- continue;
- }
- for (i = 0; i < (int) ia->count; i++) {
- mr.imr_multiaddr.s_addr = (ia->in_addrs + i)->s_addr;
- mr.imr_interface.s_addr = INADDR_ANY;
- x = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
- (char *) &mr, sizeof(struct ip_mreq));
- if (x < 0)
- debug(5, 1, "comm_join_mcast_groups: FD %d, addr: %s [%s]\n",
- fd, s->key, inet_ntoa(*(ia->in_addrs + i)));
- x = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &c, 1);
- if (x < 0)
- debug(5, 1,
- "comm_join_mcast_groups: can't disable m'cast loopback: %s\n",
- xstrerror());
-
- }
+ if (ia == NULL) {
+ debug(5, 0, "comm_join_mcast_groups: Unknown host\n");
+ return;
+ }
+ for (i = 0; i < (int) ia->count; i++) {
+ debug(5, 10, "Listening for ICP requests on %s\n",
+ inet_ntoa(*(ia->in_addrs + i)));
+ mr.imr_multiaddr.s_addr = (ia->in_addrs + i)->s_addr;
+ mr.imr_interface.s_addr = INADDR_ANY;
+ x = setsockopt(fd, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+ (char *) &mr, sizeof(struct ip_mreq));
+ if (x < 0)
+ debug(5, 1, "comm_join_mcast_groups: FD %d, [%s]\n",
+ fd, inet_ntoa(*(ia->in_addrs + i)));
+ x = setsockopt(fd, IPPROTO_IP, IP_MULTICAST_LOOP, &c, 1);
+ if (x < 0)
+ debug(5, 1,
+ "comm_join_mcast_groups: can't disable m'cast loopback: %s\n",
+ xstrerror());
}
#endif
- return 0;
}
static void
/*
- * $Id: http.cc,v 1.165 1997/06/01 18:19:52 wessels Exp $
+ * $Id: http.cc,v 1.166 1997/06/01 23:22:20 wessels Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
static CNCB httpConnectDone;
static CWCB httpSendComplete;
-static IPH httpConnect;
static PF httpReadReply;
static PF httpSendRequest;
static PF httpStateFree;
put_free_8k_page(httpState->reply_hdr);
httpState->reply_hdr = NULL;
}
- if (httpState->ip_lookup_pending)
- ipcacheUnregister(httpState->request->host, httpState);
requestUnlink(httpState->request);
requestUnlink(httpState->orig_request);
xfree(httpState);
comm_add_close_handler(httpState->fd,
httpStateFree,
httpState);
- commSetTimeout(fd, Config.Timeout.read, httpTimeout, httpState);
request->method = orig_request->method;
xstrncpy(request->host, e->host, SQUIDHOSTNAMELEN);
request->port = e->http_port;
xstrncpy(request->urlpath, entry->url, MAX_URL);
BIT_SET(request->flags, REQ_PROXYING);
- httpState->ip_lookup_pending = 1;
- ipcache_nbgethostbyname(request->host,
- httpState->fd,
- httpConnect,
- httpState);
-}
-
-static void
-httpConnect(int fd, const ipcache_addrs * ia, void *data)
-{
- HttpStateData *httpState = data;
- request_t *request = httpState->request;
- StoreEntry *entry = httpState->entry;
- httpState->ip_lookup_pending = 0;
- if (ia == NULL) {
- debug(11, 4, "httpConnect: Unknown host: %s\n", request->host);
- squid_error_entry(entry, ERR_DNS_FAIL, dns_error_message);
- comm_close(fd);
- return;
- }
- /* Open connection. */
commSetTimeout(fd, Config.Timeout.connect, httpTimeout, httpState);
- commConnectStart(fd,
+ commConnectStart(httpState->fd,
request->host,
request->port,
httpConnectDone,
HttpStateData *httpState = data;
request_t *request = httpState->request;
StoreEntry *entry = httpState->entry;
- if (status != COMM_OK) {
+ if (status == COMM_ERR_DNS) {
+ debug(11, 4, "httpConnectDone: Unknown host: %s\n", request->host);
+ squid_error_entry(entry, ERR_DNS_FAIL, dns_error_message);
+ comm_close(fd);
+ } else if (status != COMM_OK) {
squid_error_entry(entry, ERR_CONNECT_FAIL, xstrerror());
if (httpState->neighbor)
peerCheckConnectStart(httpState->neighbor);
comm_add_close_handler(httpState->fd,
httpStateFree,
httpState);
- commSetTimeout(fd, Config.Timeout.read, httpTimeout, httpState);
- httpState->ip_lookup_pending = 1;
- ipcache_nbgethostbyname(request->host,
- httpState->fd,
- httpConnect,
+ commSetTimeout(fd, Config.Timeout.connect, httpTimeout, httpState);
+ commConnectStart(httpState->fd,
+ request->host,
+ request->port,
+ httpConnectDone,
httpState);
}
/*
- * $Id: ipcache.cc,v 1.118 1997/05/23 16:56:16 wessels Exp $
+ * $Id: ipcache.cc,v 1.119 1997/06/01 23:22:23 wessels Exp $
*
* DEBUG: section 14 IP Cache
* AUTHOR: Harvest Derived
fatal_dump("ipcache_release: i != table_entry!");
if (i->locks) {
i->expires = squid_curtime;
- ipcacheChangeKey(i);
+ ipcacheChangeKey(i);
IpcacheStats.release_locked++;
return;
}
}
ipcacheUnlockEntry(i); /* unlock from IP_DISPATCHED */
} else {
- debug(14,5,"ipcache_dnsHandleRead: Incomplete reply\n");
- commSetSelect(fd,
- COMM_SELECT_READ,
- ipcache_dnsHandleRead,
- dnsData,
- 0);
+ debug(14, 5, "ipcache_dnsHandleRead: Incomplete reply\n");
+ commSetSelect(fd,
+ COMM_SELECT_READ,
+ ipcache_dnsHandleRead,
+ dnsData,
+ 0);
}
if (dnsData->offset == 0) {
dnsData->data = NULL;
/*
- * $Id: main.cc,v 1.149 1997/05/26 04:05:00 wessels Exp $
+ * $Id: main.cc,v 1.150 1997/06/01 23:22:25 wessels Exp $
*
* DEBUG: section 1 Startup and Main Loop
* AUTHOR: Harvest Derived
int len;
int x;
int fd;
+ wordlist *s;
for (x = 0; x < Config.Port.n_http; x++) {
enter_suid();
fd = comm_open(SOCK_STREAM,
COMM_SELECT_READ,
icpHandleUdp,
NULL, 0);
- comm_join_mcast_groups(theInIcpConnection);
+ for (s = Config.mcast_group_list; s; s = s->next)
+ ipcache_nbgethostbyname(s->key,
+ theInIcpConnection,
+ comm_join_mcast_groups,
+ NULL);
debug(1, 1, "Accepting ICP connections on port %d, FD %d.\n",
(int) port, theInIcpConnection);
/*
- * $Id: squid.h,v 1.117 1997/05/23 05:21:00 wessels Exp $
+ * $Id: squid.h,v 1.118 1997/06/01 23:22:27 wessels Exp $
*
* AUTHOR: Duane Wessels
*
typedef struct _cachemgr_passwd cachemgr_passwd;
typedef struct _fileMap fileMap;
typedef struct _cwstate CommWriteStateData;
+typedef struct _ipcache_addrs ipcache_addrs;
/* 32 bit integer compatability hack */
#if SIZEOF_INT == 4
extern int theOutIcpConnection; /* main.c */
extern int vizSock;
extern volatile int shutdown_pending; /* main.c */
-extern volatile int reconfigure_pending;/* main.c */
+extern volatile int reconfigure_pending; /* main.c */
extern int opt_reload_hit_only; /* main.c */
extern int opt_dns_tests; /* main.c */
extern int opt_foreground_rebuild; /* main.c */
/*
- * $Id: ssl.cc,v 1.51 1997/05/15 23:38:02 wessels Exp $
+ * $Id: ssl.cc,v 1.52 1997/06/01 23:22:28 wessels Exp $
*
* DEBUG: section 26 Secure Sockets Layer Proxy
* AUTHOR: Duane Wessels
time_t timeout;
int *size_ptr; /* pointer to size in an ConnStateData for logging */
int proxying;
- int ip_lookup_pending;
} SslStateData;
static const char *const conn_established = "HTTP/1.0 200 Connection established\r\n\r\n";
static void sslWriteClient _PARAMS((int fd, void *));
static void sslConnected _PARAMS((int fd, void *));
static void sslProxyConnected _PARAMS((int fd, void *));
-static IPH sslConnect;
static void sslErrorComplete _PARAMS((int, char *, int, int, void *));
static void sslClose _PARAMS((SslStateData * sslState));
static void sslClientClosed _PARAMS((int fd, void *));
safe_free(sslState->client.buf);
xfree(sslState->url);
requestUnlink(sslState->request);
- if (sslState->ip_lookup_pending)
- ipcacheUnregister(sslState->host, sslState);
safe_free(sslState);
}
static void
-sslConnect(int fd, const ipcache_addrs * ia, void *data)
+sslConnectDone(int fd, int status, void *data)
{
SslStateData *sslState = data;
request_t *request = sslState->request;
char *buf = NULL;
- sslState->ip_lookup_pending = 0;
- if (ia == NULL) {
+ if (status == COMM_ERR_DNS) {
debug(26, 4, "sslConnect: Unknown host: %s\n", sslState->host);
buf = squid_error_url(sslState->url,
request->method,
sslState,
xfree);
return;
- }
- debug(26, 5, "sslConnect: client=%d server=%d\n",
- sslState->client.fd,
- sslState->server.fd);
- commSetTimeout(sslState->server.fd,
- Config.Timeout.read,
- sslTimeout,
- sslState);
- commConnectStart(fd,
- sslState->host,
- sslState->port,
- sslConnectDone,
- sslState);
-}
-
-static void
-sslConnectDone(int fd, int status, void *data)
-{
- SslStateData *sslState = data;
- char *buf = NULL;
- if (status == COMM_ERROR) {
+ } else if (status != COMM_OK) {
buf = squid_error_url(sslState->url,
sslState->request->method,
ERR_CONNECT_FAIL,
} else {
sslState->port = CACHE_HTTP_PORT;
}
- sslState->ip_lookup_pending = 1;
- ipcache_nbgethostbyname(sslState->host,
- sslState->server.fd,
- sslConnect,
+ commConnectStart(sslState->server.fd,
+ sslState->host,
+ sslState->port,
+ sslConnectDone,
sslState);
}
/*
- * $Id: tunnel.cc,v 1.51 1997/05/15 23:38:02 wessels Exp $
+ * $Id: tunnel.cc,v 1.52 1997/06/01 23:22:28 wessels Exp $
*
* DEBUG: section 26 Secure Sockets Layer Proxy
* AUTHOR: Duane Wessels
time_t timeout;
int *size_ptr; /* pointer to size in an ConnStateData for logging */
int proxying;
- int ip_lookup_pending;
} SslStateData;
static const char *const conn_established = "HTTP/1.0 200 Connection established\r\n\r\n";
static void sslWriteClient _PARAMS((int fd, void *));
static void sslConnected _PARAMS((int fd, void *));
static void sslProxyConnected _PARAMS((int fd, void *));
-static IPH sslConnect;
static void sslErrorComplete _PARAMS((int, char *, int, int, void *));
static void sslClose _PARAMS((SslStateData * sslState));
static void sslClientClosed _PARAMS((int fd, void *));
safe_free(sslState->client.buf);
xfree(sslState->url);
requestUnlink(sslState->request);
- if (sslState->ip_lookup_pending)
- ipcacheUnregister(sslState->host, sslState);
safe_free(sslState);
}
static void
-sslConnect(int fd, const ipcache_addrs * ia, void *data)
+sslConnectDone(int fd, int status, void *data)
{
SslStateData *sslState = data;
request_t *request = sslState->request;
char *buf = NULL;
- sslState->ip_lookup_pending = 0;
- if (ia == NULL) {
+ if (status == COMM_ERR_DNS) {
debug(26, 4, "sslConnect: Unknown host: %s\n", sslState->host);
buf = squid_error_url(sslState->url,
request->method,
sslState,
xfree);
return;
- }
- debug(26, 5, "sslConnect: client=%d server=%d\n",
- sslState->client.fd,
- sslState->server.fd);
- commSetTimeout(sslState->server.fd,
- Config.Timeout.read,
- sslTimeout,
- sslState);
- commConnectStart(fd,
- sslState->host,
- sslState->port,
- sslConnectDone,
- sslState);
-}
-
-static void
-sslConnectDone(int fd, int status, void *data)
-{
- SslStateData *sslState = data;
- char *buf = NULL;
- if (status == COMM_ERROR) {
+ } else if (status != COMM_OK) {
buf = squid_error_url(sslState->url,
sslState->request->method,
ERR_CONNECT_FAIL,
} else {
sslState->port = CACHE_HTTP_PORT;
}
- sslState->ip_lookup_pending = 1;
- ipcache_nbgethostbyname(sslState->host,
- sslState->server.fd,
- sslConnect,
+ commConnectStart(sslState->server.fd,
+ sslState->host,
+ sslState->port,
+ sslConnectDone,
sslState);
}
/*
- * $Id: wais.cc,v 1.71 1997/05/23 05:21:04 wessels Exp $
+ * $Id: wais.cc,v 1.72 1997/06/01 23:22:29 wessels Exp $
*
* DEBUG: section 24 WAIS Relay
* AUTHOR: Harvest Derived
int relayport;
char *request_hdr;
char request[MAX_URL];
- int ip_lookup_pending;
} WaisStateData;
static PF waisStateFree;
static PF waisReadReply;
static CWCB waisSendComplete;
static PF waisSendRequest;
-static IPH waisConnect;
static CNCB waisConnectDone;
static void
if (waisState == NULL)
return;
storeUnlockObject(waisState->entry);
- if (waisState->ip_lookup_pending)
- ipcacheUnregister(waisState->relayhost, waisState);
xfree(waisState);
}
waisState);
commSetTimeout(fd, Config.Timeout.read, waisTimeout, waisState);
storeLockObject(entry);
- waisState->ip_lookup_pending = 1;
- ipcache_nbgethostbyname(waisState->relayhost,
- waisState->fd,
- waisConnect,
- waisState);
-}
-
-static void
-waisConnect(int fd, const ipcache_addrs * ia, void *data)
-{
- WaisStateData *waisState = data;
- waisState->ip_lookup_pending = 0;
- if (!ipcache_gethostbyname(waisState->relayhost, 0)) {
- debug(24, 4, "waisstart: Unknown host: %s\n", waisState->relayhost);
- squid_error_entry(waisState->entry, ERR_DNS_FAIL, dns_error_message);
- comm_close(waisState->fd);
- return;
- }
- commSetTimeout(fd, Config.Timeout.connect, waisTimeout, waisState);
- commConnectStart(fd,
+ commConnectStart(waisState->fd,
waisState->relayhost,
waisState->relayport,
waisConnectDone,
waisConnectDone(int fd, int status, void *data)
{
WaisStateData *waisState = data;
- if (status == COMM_ERROR) {
+ if (status == COMM_ERR_DNS) {
+ squid_error_entry(waisState->entry, ERR_DNS_FAIL, dns_error_message);
+ comm_close(fd);
+ return;
+ } else if (status != COMM_OK) {
squid_error_entry(waisState->entry, ERR_CONNECT_FAIL, xstrerror());
comm_close(fd);
return;
}
- /* Install connection complete handler. */
if (opt_no_ipcache)
ipcacheInvalidate(waisState->relayhost);
commSetSelect(fd,