From: wessels <> Date: Thu, 10 Oct 1996 04:49:27 +0000 (+0000) Subject: -Replaced use of hostent in IP cache. Now use home-grown ipcache_addrs with X-Git-Tag: SQUID_3_0_PRE1~5690 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e5f6c5c2bf496abccc6c5fc3ef1b36c339c85ba2;p=thirdparty%2Fsquid.git -Replaced use of hostent in IP cache. Now use home-grown ipcache_addrs with list of in_addr's -Changed comm_connect() to comm_nbconnect() and removed all *ConnInProgress() stuff. Now all (most?) completed connections go through a single function. -Added ipcacheCycleAddr() to round-robin IP addresses -Added ipcacheRemoveBadAddr() to remove bad addresses from failed connect's. -Other junk --- diff --git a/src/acl.cc b/src/acl.cc index cea50f4a76..6580e170ad 100644 --- a/src/acl.cc +++ b/src/acl.cc @@ -1,5 +1,5 @@ /* - * $Id: acl.cc,v 1.47 1996/10/09 16:27:16 wessels Exp $ + * $Id: acl.cc,v 1.48 1996/10/09 22:49:27 wessels Exp $ * * DEBUG: section 28 Access Control * AUTHOR: Duane Wessels @@ -76,21 +76,22 @@ strtokFile(void) char *t, *fn; LOCAL_ARRAY(char, buf, 256); -strtok_again: + strtok_again: if (!aclFromFile) { t = (strtok(NULL, w_space)); if (t && (*t == '\"' || *t == '\'')) { /* quote found, start reading from file */ fn = ++t; - while (*t && *t != '\"' && *t != '\'') t++; + while (*t && *t != '\"' && *t != '\'') + t++; *t = '\0'; if ((aclFile = fopen(fn, "r")) == NULL) { debug(28, 0, "strtokFile: %s not found\n", fn); - return(NULL); + return (NULL); } aclFromFile = 1; } else { - return(t); + return (t); } } /* aclFromFile */ @@ -104,7 +105,7 @@ strtok_again: /* skip leading and trailing white space */ t += strspn(buf, w_space); t[strcspn(t, w_space)] = '\0'; - return(t); + return (t); } } @@ -207,7 +208,7 @@ aclParseMethodList(void) static int decode_addr(char *asc, struct in_addr *addr, struct in_addr *mask) { - struct hostent *hp = NULL; + ipcache_addrs *ia = NULL; u_num32 a; int a1, a2, a3, a4; @@ -225,9 +226,8 @@ decode_addr(char *asc, struct in_addr *addr, struct in_addr *mask) break; } default: - if ((hp = gethostbyname(asc)) != NULL) { - /* We got a host name */ - *addr = inaddrFromHostent(hp); + if ((ia = ipcache_gethostbyname(asc, IP_BLOCKING_LOOKUP)) != NULL) { + *addr = ia->in_addrs[0]; } else { /* XXX: Here we could use getnetbyname */ debug(28, 0, "decode_addr: Invalid IP address or hostname '%s'\n", asc); @@ -680,8 +680,8 @@ aclMatchIp(struct _acl_ip_data *data, struct in_addr c) unsigned long lh, la1, la2; struct _acl_ip_data *first, *prev; - first = data; /* remember first element, this will never be moved */ - prev = NULL; /* previous element in the list */ + first = data; /* remember first element, this will never be moved */ + prev = NULL; /* previous element in the list */ while (data) { h.s_addr = c.s_addr & data->mask.s_addr; debug(28, 3, "aclMatchIp: h = %s\n", inet_ntoa(h)); @@ -692,7 +692,7 @@ aclMatchIp(struct _acl_ip_data *data, struct in_addr c) debug(28, 3, "aclMatchIp: returning 1\n"); if (prev != NULL) { /* shift the element just found to the second position - in the list */ + * in the list */ prev->next = data->next; data->next = first->next; first->next = data; @@ -731,13 +731,13 @@ aclMatchDomainList(wordlist * data, char *host) if (matchDomainName(data->key, host)) { if (prev != NULL) { /* shift the element just found to the second position - in the list */ + * in the list */ prev->next = data->next; data->next = first->next; first->next = data; } return 1; - } + } prev = data; } return 0; @@ -757,7 +757,7 @@ aclMatchRegex(relist * data, char *word) if (regexec(&data->regex, word, 0, 0, 0) == 0) { if (prev != NULL) { /* shift the element just found to the second position - in the list */ + * in the list */ prev->next = data->next; data->next = first->next; first->next = data; @@ -780,7 +780,7 @@ aclMatchInteger(intlist * data, int i) if (data->i == i) { if (prev != NULL) { /* shift the element just found to the second position - in the list */ + * in the list */ prev->next = data->next; data->next = first->next; first->next = data; @@ -817,7 +817,7 @@ int aclMatchAcl(struct _acl *acl, aclCheck_t * checklist) { request_t *r = checklist->request; - struct hostent *hp = NULL; + ipcache_addrs *ia = NULL; char *fqdn = NULL; int k; if (!acl) @@ -828,10 +828,10 @@ aclMatchAcl(struct _acl *acl, aclCheck_t * checklist) return aclMatchIp(acl->data, checklist->src_addr); /* NOTREACHED */ case ACL_DST_IP: - hp = ipcache_gethostbyname(r->host, IP_LOOKUP_IF_MISS); - if (hp) { - for (k = 0; *(hp->h_addr_list + k); k++) { - checklist->dst_addr = inaddrFromHostent(hp); + ia = ipcache_gethostbyname(r->host, IP_LOOKUP_IF_MISS); + if (ia) { + for (k = 0; k < (int) ia->count; k++) { + checklist->dst_addr = ia->in_addrs[k]; if (aclMatchIp(acl->data, checklist->dst_addr)) return 1; } diff --git a/src/cache_cf.cc b/src/cache_cf.cc index f6af7fd7c3..9ac7994c37 100644 --- a/src/cache_cf.cc +++ b/src/cache_cf.cc @@ -1,5 +1,5 @@ /* - * $Id: cache_cf.cc,v 1.105 1996/10/09 15:43:49 wessels Exp $ + * $Id: cache_cf.cc,v 1.106 1996/10/09 22:49:28 wessels Exp $ * * DEBUG: section 3 Configuration File Parsing * AUTHOR: Harvest Derived @@ -884,14 +884,14 @@ static void parseAddressLine(struct in_addr *addr) { char *token; - struct hostent *hp = NULL; + ipcache_addrs *ia = NULL; token = strtok(NULL, w_space); if (token == NULL) self_destruct(); if (inet_addr(token) != INADDR_NONE) (*addr).s_addr = inet_addr(token); - else if ((hp = gethostbyname(token))) - *addr = inaddrFromHostent(hp); + else if ((ia = ipcache_gethostbyname(token, IP_BLOCKING_LOOKUP))) + *addr = ia->in_addrs[0]; else self_destruct(); } diff --git a/src/client_side.cc b/src/client_side.cc index 50d457dae2..0a24be4fb0 100644 --- a/src/client_side.cc +++ b/src/client_side.cc @@ -1,6 +1,6 @@ /* - * $Id: client_side.cc,v 1.39 1996/10/08 14:57:06 wessels Exp $ + * $Id: client_side.cc,v 1.40 1996/10/09 22:49:29 wessels Exp $ * * DEBUG: section 33 Client-side Routines * AUTHOR: Duane Wessels @@ -33,20 +33,20 @@ static void clientRedirectDone _PARAMS((void *data, char *result)); static int icpHandleIMSReply _PARAMS((int fd, StoreEntry * entry, void *data)); -static void clientLookupDstIPDone _PARAMS((int fd, struct hostent * hp, void *data)); +static void clientLookupDstIPDone _PARAMS((int fd, ipcache_addrs *, void *data)); static void clientLookupSrcFQDNDone _PARAMS((int fd, char *fqdn, void *data)); static void -clientLookupDstIPDone(int fd, struct hostent *hp, void *data) +clientLookupDstIPDone(int fd, ipcache_addrs * ia, void *data) { icpStateData *icpState = data; debug(33, 5, "clientLookupDstIPDone: FD %d, '%s'\n", fd, icpState->url); icpState->aclChecklist->state[ACL_DST_IP] = ACL_LOOKUP_DONE; - if (hp) { - icpState->aclChecklist->dst_addr = inaddrFromHostent(hp); + if (ia) { + icpState->aclChecklist->dst_addr = ia->in_addrs[0]; debug(33, 5, "clientLookupDstIPDone: %s is %s\n", icpState->request->host, inet_ntoa(icpState->aclChecklist->dst_addr)); diff --git a/src/comm.cc b/src/comm.cc index 08b1b48ff8..47fd0d419c 100644 --- a/src/comm.cc +++ b/src/comm.cc @@ -1,6 +1,6 @@ /* - * $Id: comm.cc,v 1.86 1996/10/09 15:43:51 wessels Exp $ + * $Id: comm.cc,v 1.87 1996/10/09 22:49:29 wessels Exp $ * * DEBUG: section 5 Socket Functions * AUTHOR: Harvest Derived @@ -307,24 +307,43 @@ comm_listen(int sock) } /* Connect SOCK to specified DEST_PORT at DEST_HOST. */ -int -comm_connect(int sock, char *dest_host, u_short dest_port) +void +comm_nbconnect(int fd, void *data) { - struct hostent *hp = NULL; - static struct sockaddr_in to_addr; - - /* Set up the destination socket address for message to send to. */ - to_addr.sin_family = AF_INET; - - if ((hp = ipcache_gethostbyname(dest_host, IP_BLOCKING_LOOKUP)) == 0) { - debug(5, 3, "comm_connect: Failure to lookup host: %s.\n", dest_host); - return (COMM_ERROR); + ConnectStateData *connectState = data; + 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, "comm_nbconnect: Unknown host: %s\n", + connectState->host); + connectState->handler(fd, + COMM_ERROR, + connectState->data); + return; + } + connectState->S.sin_family = AF_INET; + connectState->S.sin_addr = ia->in_addrs[ia->cur]; + connectState->S.sin_port = htons(connectState->port); + if (Config.Log.log_fqdn) + fqdncache_gethostbyaddr(connectState->S.sin_addr, FQDN_LOOKUP_IF_MISS); + } + switch (comm_connect_addr(fd, &connectState->S)) { + case COMM_INPROGRESS: + comm_set_select_handler(fd, + COMM_SELECT_WRITE, + comm_nbconnect, + (void *) connectState); + break; + case COMM_OK: + connectState->handler(fd, COMM_OK, connectState->data); + ipcacheCycleAddr(connectState->host); + break; + default: + ipcacheRemoveBadAddr(connectState->host, connectState->S.sin_addr); + connectState->handler(fd, COMM_ERROR, connectState->data); + break; } - to_addr.sin_addr = inaddrFromHostent(hp); - to_addr.sin_port = htons(dest_port); - if (Config.Log.log_fqdn) - fqdncache_gethostbyaddr(to_addr.sin_addr, FQDN_LOOKUP_IF_MISS); - return comm_connect_addr(sock, &to_addr); } int @@ -376,7 +395,7 @@ comm_connect_addr(int sock, struct sockaddr_in *address) return COMM_ERROR; } /* Establish connection. */ - if (connect(sock, (struct sockaddr *) address, sizeof(struct sockaddr_in)) < 0) + if (connect(sock, (struct sockaddr *) address, sizeof(struct sockaddr_in)) < 0) { switch (errno) { case EALREADY: return COMM_ERROR; @@ -386,7 +405,7 @@ comm_connect_addr(int sock, struct sockaddr_in *address) #endif case EWOULDBLOCK: case EINPROGRESS: - status = EINPROGRESS; + status = COMM_INPROGRESS; break; case EISCONN: status = COMM_OK; @@ -402,6 +421,7 @@ comm_connect_addr(int sock, struct sockaddr_in *address) xstrerror()); return COMM_ERROR; } + } strcpy(conn->ipaddr, inet_ntoa(address->sin_addr)); conn->remote_port = ntohs(address->sin_port); /* set the lifetime for this client */ @@ -519,19 +539,19 @@ comm_cleanup_fd_entry(int fd) int comm_udp_send(int fd, char *host, u_short port, char *buf, int len) { - struct hostent *hp = NULL; + ipcache_addrs *ia = NULL; static struct sockaddr_in to_addr; int bytes_sent; /* Set up the destination socket address for message to send to. */ to_addr.sin_family = AF_INET; - if ((hp = ipcache_gethostbyname(host, IP_BLOCKING_LOOKUP)) == 0) { + if ((ia = ipcache_gethostbyname(host, IP_BLOCKING_LOOKUP)) == 0) { debug(5, 1, "comm_udp_send: gethostbyname failure: %s: %s\n", host, xstrerror()); return (COMM_ERROR); } - to_addr.sin_addr = inaddrFromHostent(hp); + to_addr.sin_addr = ia->in_addrs[ia->cur]; to_addr.sin_port = htons(port); if ((bytes_sent = sendto(fd, buf, len, 0, (struct sockaddr *) &to_addr, sizeof(to_addr))) < 0) { @@ -590,7 +610,7 @@ comm_select_incoming(void) int fds[3]; int N = 0; int i = 0; - int (*tmp) () = NULL; + void (*tmp) () = NULL; FD_ZERO(&read_mask); FD_ZERO(&write_mask); @@ -643,7 +663,7 @@ comm_select(time_t sec) fd_set exceptfds; fd_set readfds; fd_set writefds; - int (*tmp) () = NULL; + void (*tmp) () = NULL; int fd; int i; int maxfd; @@ -843,7 +863,7 @@ comm_set_select_handler_plus_timeout(int fd, unsigned int type, PF handler, void int comm_get_select_handler(int fd, unsigned int type, - int (**handler_ptr) _PARAMS((int, void *)), + void (**handler_ptr) _PARAMS((int, void *)), void **client_data_ptr) { if (type & COMM_SELECT_TIMEOUT) { @@ -1012,35 +1032,6 @@ commSetTcpNoDelay(int fd) } #endif -char ** -getAddressList(char *name) -{ - struct hostent *hp = NULL; - if (name == NULL) - return NULL; - if ((hp = ipcache_gethostbyname(name, IP_BLOCKING_LOOKUP))) - return hp->h_addr_list; - debug(5, 0, "getAddress: gethostbyname failure: %s: %s\n", - name, xstrerror()); - return NULL; -} - -struct in_addr * -getAddress(char *name) -{ - static struct in_addr first; - char **list = NULL; - if (name == NULL) - return NULL; - if ((list = getAddressList(name))) { - xmemcpy(&first.s_addr, *list, 4); - return (&first); - } - debug(5, 0, "getAddress: gethostbyname failure: %s: %s\n", - name, xstrerror()); - return NULL; -} - /* * the fd_lifetime is used as a hardlimit to timeout dead sockets. * The basic problem is that many WWW clients are abusive and @@ -1165,7 +1156,7 @@ static void checkTimeouts(void) { int fd; - int (*hdl) () = NULL; + void (*hdl) () = NULL; FD_ENTRY *f = NULL; void *data; /* scan for timeout */ @@ -1190,7 +1181,7 @@ checkLifetimes(void) time_t lft; FD_ENTRY *fde = NULL; - int (*func) () = NULL; + void (*func) () = NULL; for (fd = 0; fd < FD_SETSIZE; fd++) { if ((lft = comm_get_fd_lifetime(fd)) == -1) diff --git a/src/dns.cc b/src/dns.cc index d51f28bdb8..7a1947e5d6 100644 --- a/src/dns.cc +++ b/src/dns.cc @@ -1,5 +1,5 @@ /* - * $Id: dns.cc,v 1.18 1996/10/08 14:43:13 wessels Exp $ + * $Id: dns.cc,v 1.19 1996/10/09 22:49:31 wessels Exp $ * * DEBUG: section 34 Dnsserver interface * AUTHOR: Harvest Derived @@ -122,7 +122,6 @@ static int dnsOpenServer(char *command) { int pid; - u_short port; struct sockaddr_in S; int cfd; int sfd; @@ -147,8 +146,6 @@ dnsOpenServer(char *command) comm_close(cfd); return -1; } - port = ntohs(S.sin_port); - debug(34, 4, "dnsOpenServer: bind to local host.\n"); listen(cfd, 1); if ((pid = fork()) < 0) { debug(34, 0, "dnsOpenServer: fork: %s\n", xstrerror()); @@ -166,7 +163,7 @@ dnsOpenServer(char *command) NULL); /* blocking! */ if (sfd == COMM_ERROR) return -1; - if (comm_connect(sfd, localhost, port) == COMM_ERROR) { + if (comm_connect_addr(sfd, &S) == COMM_ERROR) { comm_close(sfd); return -1; } diff --git a/src/ftp.cc b/src/ftp.cc index 8dd8eaeaea..ee2748f4ba 100644 --- a/src/ftp.cc +++ b/src/ftp.cc @@ -1,6 +1,6 @@ /* - * $Id: ftp.cc,v 1.62 1996/10/09 15:34:26 wessels Exp $ + * $Id: ftp.cc,v 1.63 1996/10/09 22:49:31 wessels Exp $ * * DEBUG: section 9 File Transfer Protocol (FTP) * AUTHOR: Harvest Derived @@ -124,34 +124,35 @@ typedef struct _Ftpdata { int got_marker; /* denotes end of successful request */ int reply_hdr_state; int authenticated; /* This ftp request is authenticated */ -} FtpData; + ConnectStateData connectState; +} FtpStateData; /* Local functions */ static char *ftpTransferMode _PARAMS((char *)); static char *ftpGetBasicAuth _PARAMS((char *)); -static int ftpReadReply _PARAMS((int, FtpData *)); -static int ftpStateFree _PARAMS((int, FtpData *)); -static void ftpConnInProgress _PARAMS((int, FtpData *)); -static void ftpLifetimeExpire _PARAMS((int, FtpData *)); -static void ftpProcessReplyHeader _PARAMS((FtpData *, char *, int)); +static int ftpReadReply _PARAMS((int, FtpStateData *)); +static int ftpStateFree _PARAMS((int, FtpStateData *)); +static void ftpConnectDone _PARAMS((int fd, int status, void *data)); +static void ftpLifetimeExpire _PARAMS((int, FtpStateData *)); +static void ftpProcessReplyHeader _PARAMS((FtpStateData *, char *, int)); static void ftpSendComplete _PARAMS((int, char *, int, int, void *)); -static void ftpSendRequest _PARAMS((int, FtpData *)); +static void ftpSendRequest _PARAMS((int, FtpStateData *)); static void ftpServerClosed _PARAMS((int, void *)); -static void ftp_login_parser _PARAMS((char *, FtpData *)); +static void ftp_login_parser _PARAMS((char *, FtpStateData *)); /* Global functions not declared in ftp.h */ -void ftpLifetimeExpire(int fd, FtpData * data); -int ftpReadReply(int fd, FtpData * data); +void ftpLifetimeExpire(int fd, FtpStateData * data); +int ftpReadReply(int fd, FtpStateData * data); void ftpSendComplete(int fd, char *buf, int size, int errflag, void *ftpData); -void ftpSendRequest(int fd, FtpData * data); -void ftpConnInProgress(int fd, FtpData * data); +void ftpSendRequest(int fd, FtpStateData * data); +void ftpConnInProgress(int fd, FtpStateData * data); void ftpServerClose(void); /* External functions */ extern char *base64_decode _PARAMS((char *coded)); static int -ftpStateFree(int fd, FtpData * ftpState) +ftpStateFree(int fd, FtpStateData * ftpState) { if (ftpState == NULL) return 1; @@ -166,7 +167,7 @@ ftpStateFree(int fd, FtpData * ftpState) } static void -ftp_login_parser(char *login, FtpData * data) +ftp_login_parser(char *login, FtpStateData * data) { char *user = data->user; char *password = data->password; @@ -189,7 +190,7 @@ ftp_login_parser(char *login, FtpData * data) /* This will be called when socket lifetime is expired. */ static void -ftpLifetimeExpire(int fd, FtpData * data) +ftpLifetimeExpire(int fd, FtpStateData * data) { StoreEntry *entry = NULL; entry = data->entry; @@ -200,9 +201,9 @@ ftpLifetimeExpire(int fd, FtpData * data) /* This is too much duplicated code from httpProcessReplyHeader. Only - * difference is FtpData vs HttpData. */ + * difference is FtpStateData vs HttpData. */ static void -ftpProcessReplyHeader(FtpData * data, char *buf, int size) +ftpProcessReplyHeader(FtpStateData * data, char *buf, int size) { char *t = NULL; StoreEntry *entry = data->entry; @@ -281,7 +282,7 @@ ftpProcessReplyHeader(FtpData * data, char *buf, int size) /* This will be called when data is ready to be read from fd. Read until * error or connection closed. */ static int -ftpReadReply(int fd, FtpData * data) +ftpReadReply(int fd, FtpStateData * data) { LOCAL_ARRAY(char, buf, SQUID_TCP_SO_RCVBUF); int len; @@ -412,7 +413,7 @@ ftpReadReply(int fd, FtpData * data) static void ftpSendComplete(int fd, char *buf, int size, int errflag, void *data) { - FtpData *ftpState = (FtpData *) data; + FtpStateData *ftpState = (FtpStateData *) data; StoreEntry *entry = NULL; entry = ftpState->entry; @@ -460,7 +461,7 @@ ftpTransferMode(char *urlpath) } static void -ftpSendRequest(int fd, FtpData * data) +ftpSendRequest(int fd, FtpStateData * data) { char *path = NULL; char *mode = NULL; @@ -540,38 +541,6 @@ ftpSendRequest(int fd, FtpData * data) put_free_8k_page); } -static void -ftpConnInProgress(int fd, FtpData * data) -{ - StoreEntry *entry = data->entry; - - debug(9, 5, "ftpConnInProgress: FD %d\n", fd); - - if (comm_connect(fd, localhost, ftpget_port) != COMM_OK) { - switch (errno) { - case EINPROGRESS: - case EALREADY: - /* schedule this handler again */ - comm_set_select_handler(fd, - COMM_SELECT_WRITE, - (PF) ftpConnInProgress, - (void *) data); - return; - default: - squid_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); - comm_close(fd); - return; - } - } - /* Call the real write handler, now that we're fully connected */ - comm_set_select_handler(fd, - COMM_SELECT_WRITE, - (PF) ftpSendRequest, - (void *) data); - if (opt_no_ipcache) - ipcacheInvalidate(data->request->host); -} - static char * ftpGetBasicAuth(char *req_hdr) { @@ -595,98 +564,98 @@ int ftpStart(int unusedfd, char *url, request_t * request, StoreEntry * entry) { LOCAL_ARRAY(char, realm, 8192); - FtpData *data = NULL; + FtpStateData *ftpData = NULL; char *req_hdr = entry->mem_obj->mime_hdr; char *response; char *auth; - int status; - debug(9, 3, "FtpStart: FD %d \n", unusedfd, url); - data = xcalloc(1, sizeof(FtpData)); - storeLockObject(data->entry = entry, NULL, NULL); - data->request = requestLink(request); + ftpData = xcalloc(1, sizeof(FtpStateData)); + storeLockObject(ftpData->entry = entry, NULL, NULL); + ftpData->request = requestLink(request); /* Parse login info. */ if ((auth = ftpGetBasicAuth(req_hdr))) { - ftp_login_parser(auth, data); - data->authenticated = 1; + ftp_login_parser(auth, ftpData); + ftpData->authenticated = 1; } else { - ftp_login_parser(request->login, data); - if (*data->user && !*data->password) { + ftp_login_parser(request->login, ftpData); + if (*ftpData->user && !*ftpData->password) { /* This request is not fully authenticated */ if (request->port == 21) { - sprintf(realm, "ftp %s", data->user); + sprintf(realm, "ftp %s", ftpData->user); } else { sprintf(realm, "ftp %s port %d", - data->user, request->port); + ftpData->user, request->port); } response = authorization_needed_msg(request, realm); storeAppend(entry, response, strlen(response)); httpParseHeaders(response, entry->mem_obj->reply); storeComplete(entry); - ftpStateFree(-1, data); + ftpStateFree(-1, ftpData); return COMM_OK; } } debug(9, 5, "FtpStart: FD %d, host=%s, path=%s, user=%s, passwd=%s\n", - unusedfd, data->request->host, data->request->urlpath, - data->user, data->password); + unusedfd, ftpData->request->host, ftpData->request->urlpath, + ftpData->user, ftpData->password); - data->ftp_fd = comm_open(SOCK_STREAM, + ftpData->ftp_fd = comm_open(SOCK_STREAM, 0, local_addr, 0, COMM_NONBLOCKING, url); - if (data->ftp_fd == COMM_ERROR) { + if (ftpData->ftp_fd == COMM_ERROR) { squid_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); - ftpStateFree(-1, data); + ftpStateFree(-1, ftpData); return COMM_ERROR; } /* Pipe/socket created ok */ /* register close handler */ - comm_add_close_handler(data->ftp_fd, + comm_add_close_handler(ftpData->ftp_fd, (PF) ftpStateFree, - (void *) data); + (void *) ftpData); /* Now connect ... */ - if ((status = comm_connect(data->ftp_fd, localhost, ftpget_port))) { - if (status != EINPROGRESS) { - squid_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); - comm_close(data->ftp_fd); - return COMM_ERROR; - } else { - debug(9, 5, "ftpStart: FD %d: EINPROGRESS.\n", data->ftp_fd); - comm_set_select_handler(data->ftp_fd, COMM_SELECT_LIFETIME, - (PF) ftpLifetimeExpire, (void *) data); - comm_set_select_handler(data->ftp_fd, COMM_SELECT_WRITE, - (PF) ftpConnInProgress, (void *) data); - return COMM_OK; - } - } - fdstat_open(data->ftp_fd, FD_SOCKET); - commSetNonBlocking(data->ftp_fd); - (void) fd_note(data->ftp_fd, entry->url); + ftpData->connectState.fd = ftpData->ftp_fd; + ftpData->connectState.host = localhost; + ftpData->connectState.port = ftpget_port; + ftpData->connectState.handler = ftpConnectDone; + ftpData->connectState.data = ftpData; + comm_nbconnect(ftpData->ftp_fd, &ftpData->connectState); + return COMM_OK; +} +static void +ftpConnectDone(int fd, int status, void *data) +{ + FtpStateData *ftpData = data; + if (status == COMM_ERROR) { + squid_error_entry(ftpData->entry, ERR_CONNECT_FAIL, xstrerror()); + comm_close(fd); + return; + } + fdstat_open(fd, FD_SOCKET); + commSetNonBlocking(fd); + (void) fd_note(fd, ftpData->entry->url); /* Install connection complete handler. */ - fd_note(data->ftp_fd, entry->url); - comm_set_select_handler(data->ftp_fd, + fd_note(fd, ftpData->entry->url); + comm_set_select_handler(fd, COMM_SELECT_WRITE, (PF) ftpSendRequest, (void *) data); - comm_set_fd_lifetime(data->ftp_fd, + comm_set_fd_lifetime(fd, Config.lifetimeDefault); - comm_set_select_handler(data->ftp_fd, + comm_set_select_handler(fd, COMM_SELECT_LIFETIME, (PF) ftpLifetimeExpire, - (void *) data); + (void *) ftpData); if (opt_no_ipcache) - ipcacheInvalidate(data->request->host); - return COMM_OK; + ipcacheInvalidate(ftpData->request->host); } static void diff --git a/src/gopher.cc b/src/gopher.cc index 616caf9530..b6634e05e6 100644 --- a/src/gopher.cc +++ b/src/gopher.cc @@ -1,5 +1,5 @@ /* - * $Id: gopher.cc,v 1.51 1996/09/23 22:13:30 wessels Exp $ + * $Id: gopher.cc,v 1.52 1996/10/09 22:49:32 wessels Exp $ * * DEBUG: section 10 Gopher * AUTHOR: Harvest Derived @@ -156,6 +156,7 @@ typedef struct gopher_ds { int cso_recno; int len; char *buf; /* pts to a 4k page */ + ConnectStateData connectState; } GopherStateData; static int gopherStateFree _PARAMS((int fd, GopherStateData *)); @@ -178,6 +179,7 @@ static void gopherSendComplete(int fd, void *data); static void gopherSendRequest _PARAMS((int fd, GopherStateData *)); static GopherStateData *CreateGopherStateData _PARAMS((void)); +static void gopherConnectDone _PARAMS((int fd, int status, void *data)); static char def_gopher_bin[] = "www/unknown"; static char def_gopher_text[] = "text/plain"; @@ -957,7 +959,7 @@ int gopherStart(int unusedfd, char *url, StoreEntry * entry) { /* Create state structure. */ - int sock, status; + int sock; GopherStateData *data = CreateGopherStateData(); storeLockObject(data->entry = entry, NULL, NULL); @@ -1018,28 +1020,35 @@ gopherStart(int unusedfd, char *url, StoreEntry * entry) comm_close(sock); return COMM_OK; } - /* Open connection. */ - if ((status = comm_connect(sock, data->host, data->port)) != 0) { - if (status != EINPROGRESS) { - squid_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); - comm_close(sock); - return COMM_ERROR; - } else { - debug(10, 5, "startGopher: conn %d EINPROGRESS\n", sock); - } + data->connectState.fd = sock; + data->connectState.host = data->host; + data->connectState.port = data->port; + data->connectState.handler = gopherConnectDone; + data->connectState.data = data; + comm_nbconnect(sock, &data->connectState); + return COMM_OK; +} + +static void +gopherConnectDone(int fd, int status, void *data) +{ + GopherStateData *gopherState = data; + if (status == COMM_ERROR) { + squid_error_entry(gopherState->entry, ERR_CONNECT_FAIL, xstrerror()); + comm_close(fd); + return; } /* Install connection complete handler. */ if (opt_no_ipcache) - ipcacheInvalidate(data->host); - comm_set_select_handler(sock, + ipcacheInvalidate(gopherState->host); + comm_set_select_handler(fd, COMM_SELECT_LIFETIME, (PF) gopherLifetimeExpire, - (void *) data); - comm_set_select_handler(sock, + (void *) gopherState); + comm_set_select_handler(fd, COMM_SELECT_WRITE, (PF) gopherSendRequest, - (void *) data); - return COMM_OK; + (void *) gopherState); } diff --git a/src/http.cc b/src/http.cc index fbdfcfc099..6d799c6cc7 100644 --- a/src/http.cc +++ b/src/http.cc @@ -1,5 +1,5 @@ /* - * $Id: http.cc,v 1.81 1996/10/09 15:34:29 wessels Exp $ + * $Id: http.cc,v 1.82 1996/10/09 22:49:33 wessels Exp $ * * DEBUG: section 11 Hypertext Transfer Protocol (HTTP) * AUTHOR: Harvest Derived @@ -125,8 +125,8 @@ static void httpCacheNegatively _PARAMS((StoreEntry *)); static void httpReadReply _PARAMS((int fd, HttpStateData *)); static void httpSendComplete _PARAMS((int fd, char *, int, int, void *)); static void httpSendRequest _PARAMS((int fd, HttpStateData *)); -static void httpConnInProgress _PARAMS((int fd, HttpStateData *)); -static void httpConnect _PARAMS((int fd, struct hostent *, void *)); +static void httpConnect _PARAMS((int fd, ipcache_addrs *, void *)); +static void httpConnectDone _PARAMS((int fd, int status, void *data)); static int httpStateFree(int fd, HttpStateData * httpState) @@ -649,38 +649,6 @@ httpSendRequest(int fd, HttpStateData * httpState) buftype == BUF_TYPE_8K ? put_free_8k_page : xfree); } -static void -httpConnInProgress(int fd, HttpStateData * httpState) -{ - StoreEntry *entry = httpState->entry; - request_t *req = httpState->request; - - debug(11, 5, "httpConnInProgress: FD %d httpState=%p\n", fd, httpState); - - if (comm_connect(fd, req->host, req->port) != COMM_OK) { - debug(11, 5, "httpConnInProgress: FD %d: %s\n", fd, xstrerror()); - switch (errno) { - case EINPROGRESS: - case EALREADY: - /* schedule this handler again */ - comm_set_select_handler(fd, - COMM_SELECT_WRITE, - (PF) httpConnInProgress, - (void *) httpState); - return; - default: - squid_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); - comm_close(fd); - return; - } - } - /* Call the real write handler, now that we're fully connected */ - if (opt_no_ipcache) - ipcacheInvalidate(entry->mem_obj->request->host); - comm_set_select_handler(fd, COMM_SELECT_WRITE, - (PF) httpSendRequest, (void *) httpState); -} - int proxyhttpStart(edge * e, char *url, StoreEntry * entry) { @@ -731,46 +699,50 @@ proxyhttpStart(edge * e, char *url, StoreEntry * entry) } static void -httpConnect(int fd, struct hostent *hp, void *data) +httpConnect(int fd, ipcache_addrs * ia, void *data) { HttpStateData *httpState = data; request_t *request = httpState->request; StoreEntry *entry = httpState->entry; - edge *e = NULL; - int status; - if (hp == NULL) { + 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. */ - if ((status = comm_connect(fd, request->host, request->port))) { - if (status != EINPROGRESS) { - squid_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); - comm_close(fd); - if ((e = httpState->neighbor)) { - e->last_fail_time = squid_curtime; - e->neighbor_up = 0; - } - return; - } else { - debug(11, 5, "proxyhttpStart: FD %d: EINPROGRESS.\n", fd); - comm_set_select_handler(fd, COMM_SELECT_LIFETIME, - (PF) httpLifetimeExpire, (void *) httpState); - comm_set_select_handler(fd, COMM_SELECT_WRITE, - (PF) httpConnInProgress, (void *) httpState); - return; + httpState->connectState.fd = fd; + httpState->connectState.host = request->host; + httpState->connectState.port = request->port; + httpState->connectState.handler = httpConnectDone; + httpState->connectState.data = httpState; + comm_nbconnect(fd, &httpState->connectState); +} + +static void +httpConnectDone(int fd, int status, void *data) +{ + HttpStateData *httpState = data; + request_t *request = httpState->request; + StoreEntry *entry = httpState->entry; + edge *e = NULL; + if (status != COMM_OK) { + if ((e = httpState->neighbor)) { + e->last_fail_time = squid_curtime; + e->neighbor_up = 0; } + squid_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); + comm_close(fd); + } else { + /* Install connection complete handler. */ + if (opt_no_ipcache) + ipcacheInvalidate(request->host); + fd_note(fd, entry->url); + comm_set_select_handler(fd, COMM_SELECT_LIFETIME, + (PF) httpLifetimeExpire, (void *) httpState); + comm_set_select_handler(fd, COMM_SELECT_WRITE, + (PF) httpSendRequest, (void *) httpState); } - /* Install connection complete handler. */ - if (opt_no_ipcache) - ipcacheInvalidate(request->host); - fd_note(fd, entry->url); - comm_set_select_handler(fd, COMM_SELECT_LIFETIME, - (PF) httpLifetimeExpire, (void *) httpState); - comm_set_select_handler(fd, COMM_SELECT_WRITE, - (PF) httpSendRequest, (void *) httpState); } int diff --git a/src/icmp.cc b/src/icmp.cc index 4bdadb9b64..66255086d5 100644 --- a/src/icmp.cc +++ b/src/icmp.cc @@ -1,6 +1,6 @@ /* - * $Id: icmp.cc,v 1.13 1996/09/24 20:17:30 wessels Exp $ + * $Id: icmp.cc,v 1.14 1996/10/09 22:49:34 wessels Exp $ * * DEBUG: section 37 ICMP Routines * AUTHOR: Duane Wessels @@ -121,7 +121,14 @@ icmpOpen(void) void icmpClose(void) { + icmpQueueData *queue; comm_close(icmp_sock); + while ((queue = IcmpQueueHead)) { + IcmpQueueHead = queue->next; + if (queue->free) + queue->free(queue->msg); + safe_free(queue); + } } static void diff --git a/src/ident.cc b/src/ident.cc index ae71767a8f..37b851a4c6 100644 --- a/src/ident.cc +++ b/src/ident.cc @@ -1,5 +1,5 @@ /* - * $Id: ident.cc,v 1.16 1996/09/20 06:28:54 wessels Exp $ + * $Id: ident.cc,v 1.17 1996/10/09 22:49:36 wessels Exp $ * * DEBUG: section 30 Ident (RFC 931) * AUTHOR: Duane Wessels @@ -35,6 +35,7 @@ static void identRequestComplete _PARAMS((int, char *, int, int, void *)); static void identReadReply _PARAMS((int, icpStateData *)); static void identClose _PARAMS((int, icpStateData *)); +static void identConnectDone _PARAMS((int fd, int status, void *data)); static void identClose(int fd, icpStateData * icpState) @@ -44,50 +45,50 @@ identClose(int fd, icpStateData * icpState) /* start a TCP connection to the peer host on port 113 */ void -identStart(int sock, icpStateData * icpState) +identStart(int fd, icpStateData * icpState) { - char *host; - LOCAL_ARRAY(char, reqbuf, BUFSIZ); - int status; - - host = inet_ntoa(icpState->peer.sin_addr); - - if (sock < 0) { - sock = comm_open(SOCK_STREAM, + if (fd < 0) { + fd = comm_open(SOCK_STREAM, 0, Config.Addrs.tcp_outgoing, 0, COMM_NONBLOCKING, "ident"); - if (sock == COMM_ERROR) + if (fd == COMM_ERROR) return; } - icpState->ident_fd = sock; - comm_add_close_handler(sock, + icpState->ident_fd = fd; + comm_add_close_handler(fd, (PF) identClose, (void *) icpState); - if ((status = comm_connect(sock, host, IDENT_PORT)) < 0) { - if (status != EINPROGRESS) { - comm_close(sock); - return; /* die silently */ - } - comm_set_select_handler(sock, - COMM_SELECT_WRITE, - (PF) identStart, - (void *) icpState); - return; + icpState->identConnectState.fd = fd; + icpState->identConnectState.host = inet_ntoa(icpState->peer.sin_addr); + icpState->identConnectState.port = IDENT_PORT; + icpState->identConnectState.handler = identConnectDone; + icpState->identConnectState.data = icpState; + comm_nbconnect(fd, &icpState->identConnectState); +} + +static void +identConnectDone(int fd, int status, void *data) +{ + icpStateData *icpState = data; + LOCAL_ARRAY(char, reqbuf, BUFSIZ); + if (status == COMM_ERROR) { + comm_close(fd); + return; /* die silently */ } sprintf(reqbuf, "%d, %d\r\n", ntohs(icpState->peer.sin_port), ntohs(icpState->me.sin_port)); - comm_write(sock, + comm_write(fd, reqbuf, strlen(reqbuf), 5, /* timeout */ identRequestComplete, (void *) icpState, NULL); - comm_set_select_handler(sock, + comm_set_select_handler(fd, COMM_SELECT_READ, (PF) identReadReply, (void *) icpState); diff --git a/src/ipcache.cc b/src/ipcache.cc index 3762737733..5c6fc57d75 100644 --- a/src/ipcache.cc +++ b/src/ipcache.cc @@ -1,5 +1,5 @@ /* - * $Id: ipcache.cc,v 1.67 1996/10/09 15:34:31 wessels Exp $ + * $Id: ipcache.cc,v 1.68 1996/10/09 22:49:37 wessels Exp $ * * DEBUG: section 14 IP Cache * AUTHOR: Harvest Derived @@ -148,18 +148,18 @@ static void ipcache_call_pending _PARAMS((ipcache_entry *)); static void ipcache_add _PARAMS((char *, ipcache_entry *, struct hostent *, int)); static int ipcacheHasPending _PARAMS((ipcache_entry *)); static ipcache_entry *ipcache_get _PARAMS((char *)); -static void dummy_handler _PARAMS((int, struct hostent * hp, void *)); +static void dummy_handler _PARAMS((int, ipcache_addrs *, void *)); static int ipcacheExpiredEntry _PARAMS((ipcache_entry *)); static void ipcacheAddPending _PARAMS((ipcache_entry *, int fd, IPH, void *)); static void ipcacheEnqueue _PARAMS((ipcache_entry *)); static void *ipcacheDequeue _PARAMS((void)); static void ipcache_dnsDispatch _PARAMS((dnsserver_t *, ipcache_entry *)); -static struct hostent *ipcacheCheckNumeric _PARAMS((char *name)); +static ipcache_addrs *ipcacheCheckNumeric _PARAMS((char *name)); static void ipcacheStatPrint _PARAMS((ipcache_entry *, StoreEntry *)); static void ipcacheUnlockEntry _PARAMS((ipcache_entry *)); static void ipcacheLockEntry _PARAMS((ipcache_entry *)); -static struct hostent *static_result = NULL; +static ipcache_addrs static_addrs; static HashID ip_table = 0; static struct ipcacheQueueData *ipcacheQueueHead = NULL; static struct ipcacheQueueData **ipcacheQueueTailP = &ipcacheQueueHead; @@ -220,7 +220,6 @@ static void ipcache_release(ipcache_entry * i) { hash_link *table_entry = NULL; - int k; if ((table_entry = hash_lookup(ip_table, i->name)) == NULL) { debug(14, 0, "ipcache_release: Could not find key '%s'\n", i->name); @@ -242,13 +241,7 @@ ipcache_release(ipcache_entry * i) return; } if (i->status == IP_CACHED) { - for (k = 0; k < (int) i->addr_count; k++) - safe_free(*(i->entry.h_addr_list + k)); - safe_free(i->entry.h_addr_list); - for (k = 0; k < (int) i->alias_count; k++) - safe_free(i->entry.h_aliases[k]); - safe_free(i->entry.h_aliases); - safe_free(i->entry.h_name); + safe_free(i->addrs.in_addrs); debug(14, 5, "ipcache_release: Released IP cached record for '%s'.\n", i->name); } @@ -396,7 +389,6 @@ ipcache_create(void) new = xcalloc(1, sizeof(ipcache_entry)); /* set default to 4, in case parser fail to get token $h_length from * dnsserver. */ - new->entry.h_length = 4; new->expires = squid_curtime + Config.negativeDnsTtl; return new; @@ -417,7 +409,6 @@ static void ipcache_add(char *name, ipcache_entry * i, struct hostent *hp, int cached) { int addr_count; - int alias_count; int k; if (ipcache_get(name)) @@ -430,34 +421,12 @@ ipcache_add(char *name, ipcache_entry * i, struct hostent *hp, int cached) addr_count = 0; while ((addr_count < 255) && *(hp->h_addr_list + addr_count)) ++addr_count; - - i->addr_count = (unsigned char) addr_count; - - /* count for Alias */ - alias_count = 0; - if (hp->h_aliases) - while ((alias_count < 255) && hp->h_aliases[alias_count]) - ++alias_count; - - i->alias_count = (unsigned char) alias_count; - - /* copy ip addresses information */ - i->entry.h_addr_list = xcalloc(addr_count + 1, sizeof(char *)); - for (k = 0; k < addr_count; k++) { - *(i->entry.h_addr_list + k) = xcalloc(1, hp->h_length); - xmemcpy(*(i->entry.h_addr_list + k), *(hp->h_addr_list + k), hp->h_length); - } - - if (alias_count) { - /* copy aliases information */ - i->entry.h_aliases = xcalloc(alias_count + 1, sizeof(char *)); - for (k = 0; k < alias_count; k++) { - i->entry.h_aliases[k] = xcalloc(1, strlen(hp->h_aliases[k]) + 1); - strcpy(i->entry.h_aliases[k], hp->h_aliases[k]); - } - } - i->entry.h_length = hp->h_length; - i->entry.h_name = xstrdup(hp->h_name); + i->addrs.count = (unsigned char) addr_count; + i->addrs.in_addrs = xcalloc(addr_count, sizeof(struct in_addr)); + for (k = 0; k < addr_count; k++) + memcpy(&i->addrs.in_addrs[k].s_addr, + *(hp->h_addr_list + k), + hp->h_length); i->status = IP_CACHED; i->expires = squid_curtime + Config.positiveDnsTtl; } else { @@ -484,7 +453,7 @@ ipcache_call_pending(ipcache_entry * i) nhandler++; dns_error_message = i->error_message; p->handler(p->fd, - (i->status == IP_CACHED) ? &(i->entry) : NULL, + i->status == IP_CACHED ? &i->addrs : NULL, p->handlerData); } memset(p, '\0', sizeof(struct _ip_pending)); @@ -529,42 +498,33 @@ ipcache_parsebuffer(char *inbuf, dnsserver_t * dnsData) } else if (!strcmp(token, "$h_name")) { if ((token = strtok(NULL, w_space)) == NULL) fatal_dump("Invalid $h_name"); - i.entry.h_name = xstrdup(token); + /* ignore $h_name */ } else if (!strcmp(token, "$h_len")) { if ((token = strtok(NULL, w_space)) == NULL) fatal_dump("Invalid $h_len"); - i.entry.h_length = atoi(token); + /* ignore $h_length */ } else if (!strcmp(token, "$ipcount")) { if ((token = strtok(NULL, w_space)) == NULL) fatal_dump("Invalid $ipcount"); ipcount = atoi(token); - i.addr_count = (unsigned char) ipcount; + i.addrs.count = (unsigned char) ipcount; if (ipcount == 0) { - i.entry.h_addr_list = NULL; + i.addrs.in_addrs = NULL; } else { - i.entry.h_addr_list = xcalloc(ipcount + 1, sizeof(char *)); + i.addrs.in_addrs = xcalloc(ipcount, sizeof(struct in_addr)); } for (k = 0; k < ipcount; k++) { if ((token = strtok(NULL, w_space)) == NULL) fatal_dump("Invalid IP address"); - *(i.entry.h_addr_list + k) = xcalloc(1, i.entry.h_length); - *((u_num32 *) (void *) *(i.entry.h_addr_list + k)) - = inet_addr(token); + i.addrs.in_addrs[k].s_addr = inet_addr(token); } } else if (!strcmp(token, "$aliascount")) { if ((token = strtok(NULL, w_space)) == NULL) fatal_dump("Invalid $aliascount"); aliascount = atoi(token); - i.alias_count = (unsigned char) aliascount; - if (aliascount == 0) { - i.entry.h_aliases = NULL; - } else { - i.entry.h_aliases = xcalloc(aliascount, sizeof(char *)); - } for (k = 0; k < aliascount; k++) { if ((token = strtok(NULL, w_space)) == NULL) fatal_dump("Invalid alias"); - *(i.entry.h_aliases + k) = xstrdup(token); } } else if (!strcmp(token, "$ttl")) { if ((token = strtok(NULL, w_space)) == NULL) @@ -624,9 +584,7 @@ ipcache_dnsHandleRead(int fd, dnsserver_t * dnsData) dnsData->offset = 0; dnsData->ip_inbuf[0] = '\0'; i = dnsData->data; - i->addr_count = x->addr_count; - i->alias_count = x->alias_count; - i->entry = x->entry; + i->addrs = x->addrs; i->error_message = x->error_message; i->status = x->status; i->expires = x->expires; @@ -665,7 +623,7 @@ ipcache_nbgethostbyname(char *name, int fd, IPH handler, void *handlerData) { ipcache_entry *i = NULL; dnsserver_t *dnsData = NULL; - struct hostent *hp = NULL; + ipcache_addrs *addrs; if (!handler) fatal_dump("ipcache_nbgethostbyname: NULL handler"); @@ -678,8 +636,8 @@ ipcache_nbgethostbyname(char *name, int fd, IPH handler, void *handlerData) handler(fd, NULL, handlerData); return; } - if ((hp = ipcacheCheckNumeric(name))) { - handler(fd, hp, handlerData); + if ((addrs = ipcacheCheckNumeric(name))) { + handler(fd, addrs, handlerData); return; } if ((i = ipcache_get(name))) { @@ -777,12 +735,8 @@ ipcache_init(void) } ip_table = hash_create(urlcmp, 229, hash_string); /* small hash table */ - /* init static area */ - static_result = xcalloc(1, sizeof(struct hostent)); - static_result->h_length = 4; - static_result->h_addr_list = xcalloc(2, sizeof(char *)); - *(static_result->h_addr_list + 0) = xcalloc(1, 4); - static_result->h_name = xcalloc(1, SQUIDHOSTNAMELEN + 1); + memset(&static_addrs, '\0', sizeof(ipcache_addrs)); + static_addrs.in_addrs = xcalloc(1, sizeof(struct in_addr)); ipcache_high = (long) (((float) Config.ipcache.size * (float) Config.ipcache.high) / (float) 100); @@ -815,11 +769,12 @@ ipcache_unregister(char *name, int fd) return n; } -struct hostent * +ipcache_addrs * ipcache_gethostbyname(char *name, int flags) { ipcache_entry *i = NULL; - struct hostent *hp = NULL; + ipcache_addrs *addrs; + struct hostent *hp; if (!name) fatal_dump("ipcache_gethostbyname: NULL name"); @@ -841,12 +796,12 @@ ipcache_gethostbyname(char *name, int flags) } else { IpcacheStats.hits++; i->lastref = squid_curtime; - return &i->entry; + return &i->addrs; } } IpcacheStats.misses++; - if ((hp = ipcacheCheckNumeric(name))) - return hp; + if ((addrs = ipcacheCheckNumeric(name))) + return addrs; if (flags & IP_BLOCKING_LOOKUP) { IpcacheStats.ghbn_calls++; hp = gethostbyname(name); @@ -856,7 +811,7 @@ ipcache_gethostbyname(char *name, int flags) i = ipcache_get(name); i->lastref = squid_curtime; i->expires = squid_curtime + Config.positiveDnsTtl; - return &i->entry; + return &i->addrs; } /* bad address, negative cached */ if (ip_table) { @@ -876,21 +831,15 @@ static void ipcacheStatPrint(ipcache_entry * i, StoreEntry * sentry) { int k; - struct in_addr addr; storeAppendPrintf(sentry, " {%-32.32s %c%c %6d %6d %d", i->name, ipcache_status_char[i->status], i->locks ? 'L' : ' ', (int) (squid_curtime - i->lastref), (int) (i->expires - squid_curtime), - i->addr_count); - for (k = 0; k < (int) i->addr_count; k++) - xmemcpy(&addr.s_addr, i->entry.h_addr_list[k], sizeof(struct in_addr)); - storeAppendPrintf(sentry, " %15s", inet_ntoa(addr)); - for (k = 0; k < (int) i->alias_count; k++) - storeAppendPrintf(sentry, " %s", i->entry.h_aliases[k]); - if (i->entry.h_name && strncmp(i->name, i->entry.h_name, MAX_LINELEN)) - storeAppendPrintf(sentry, " %s", i->entry.h_name); + (int) i->addrs.count); + for (k = 0; k < (int) i->addrs.count; k++) + storeAppendPrintf(sentry, " %15s", inet_ntoa(i->addrs.in_addrs[k])); storeAppendPrintf(sentry, close_bracket); } @@ -949,7 +898,7 @@ stat_ipcache_get(StoreEntry * sentry) } static void -dummy_handler(int u1, struct hostent *u2, void *u3) +dummy_handler(int u1, ipcache_addrs * addrs, void *u3) { return; } @@ -989,16 +938,17 @@ ipcacheInvalidate(char *name) * FMR */ } -static struct hostent * +static ipcache_addrs * ipcacheCheckNumeric(char *name) { unsigned int ip; /* check if it's already a IP address in text form. */ if ((ip = inet_addr(name)) == INADDR_NONE) return NULL; - *((u_num32 *) (void *) static_result->h_addr_list[0]) = ip; - strncpy(static_result->h_name, name, SQUIDHOSTNAMELEN); - return static_result; + static_addrs.count = 1; + static_addrs.cur = 0; + static_addrs.in_addrs[0].s_addr = ip; + return &static_addrs; } int @@ -1026,3 +976,37 @@ ipcacheUnlockEntry(ipcache_entry * i) if (ipcacheExpiredEntry(i)) ipcache_release(i); } + +void +ipcacheCycleAddr(char *name) +{ + ipcache_entry *i; + if ((i = ipcache_get(name)) == NULL) + return; + if (i->status != IP_CACHED) + return; + if (++i->addrs.cur == i->addrs.count) + i->addrs.cur = 0; +} + +void +ipcacheRemoveBadAddr(char *name, struct in_addr addr) +{ + ipcache_entry *i; + ipcache_addrs *ia; + int k; + if ((i = ipcache_get(name)) == NULL) + return; + ia = &i->addrs; + for (k = 0; k < (int) ia->count; k++) { + if (ia->in_addrs[k].s_addr == addr.s_addr) + break; + } + if (k == (int) ia->count) + return; + ia->in_addrs[k] = ia->in_addrs[--ia->count]; + if (ia->count == 0) + i->expires = squid_curtime; + if (ia->cur >= ia->count) + ia->cur = 0; +} diff --git a/src/neighbors.cc b/src/neighbors.cc index 87ed346e3d..520314effa 100644 --- a/src/neighbors.cc +++ b/src/neighbors.cc @@ -1,5 +1,5 @@ /* - * $Id: neighbors.cc,v 1.62 1996/10/09 15:43:53 wessels Exp $ + * $Id: neighbors.cc,v 1.63 1996/10/09 22:49:38 wessels Exp $ * * DEBUG: section 15 Neighbor Routines * AUTHOR: Harvest Derived @@ -321,11 +321,10 @@ neighbors_open(int fd) struct sockaddr_in name; struct sockaddr_in *ap; int len = sizeof(struct sockaddr_in); - char **list = NULL; + ipcache_addrs *ia = NULL; edge *e = NULL; edge *next = NULL; edge **E = NULL; - struct in_addr *ina = NULL; struct servent *sep = NULL; memset(&name, '\0', sizeof(struct sockaddr_in)); @@ -338,7 +337,7 @@ neighbors_open(int fd) while ((e = next)) { next = e->next; debug(15, 2, "Finding IP addresses for '%s'\n", e->host); - if ((list = getAddressList(e->host)) == NULL) { + if ((ia = ipcache_gethostbyname(e->host, IP_BLOCKING_LOOKUP)) == NULL) { debug(0, 0, "WARNING!!: DNS lookup for '%s' failed!\n", e->host); debug(0, 0, "THIS NEIGHBOR WILL BE IGNORED.\n"); *E = next; /* skip */ @@ -346,10 +345,8 @@ neighbors_open(int fd) continue; } e->n_addresses = 0; - for (j = 0; *list && j < EDGE_MAX_ADDRESSES; j++) { - ina = &e->addresses[j]; - xmemcpy(&(ina->s_addr), *list, 4); - list++; + for (j = 0; j < (int) ia->count && j < EDGE_MAX_ADDRESSES; j++) { + e->addresses[j] = ia->in_addrs[j]; e->n_addresses++; } if (e->n_addresses < 1) { @@ -396,7 +393,7 @@ neighborsUdpPing(protodispatch_data * proto) char *host = proto->request->host; char *url = proto->url; StoreEntry *entry = proto->entry; - struct hostent *hep = NULL; + ipcache_addrs *ia = NULL; struct sockaddr_in to_addr; edge *e = NULL; int i; @@ -504,17 +501,17 @@ neighborsUdpPing(protodispatch_data * proto) if (friends->n) { if (!proto->source_ping) { debug(15, 6, "neighborsUdpPing: Source Ping is disabled.\n"); - } else if ((hep = ipcache_gethostbyname(host, IP_BLOCKING_LOOKUP))) { + } else if ((ia = ipcache_gethostbyname(host, IP_BLOCKING_LOOKUP))) { debug(15, 6, "neighborsUdpPing: Source Ping: to %s for '%s'\n", host, url); echo_hdr.reqnum = reqnum; #if USE_ICMP if (icmp_sock != -1) { - icmpSourcePing(inaddrFromHostent(hep), &echo_hdr, url); + icmpSourcePing(ia->in_addrs[ia->cur], &echo_hdr, url); } else { #endif to_addr.sin_family = AF_INET; - to_addr.sin_addr = inaddrFromHostent(hep); + to_addr.sin_addr = ia->in_addrs[ia->cur]; to_addr.sin_port = htons(echo_port); icpUdpSend(theOutIcpConnection, url, diff --git a/src/net_db.cc b/src/net_db.cc index 8ca0a52806..cf1f89f0c7 100644 --- a/src/net_db.cc +++ b/src/net_db.cc @@ -3,7 +3,7 @@ #include "squid.h" -#define NET_DB_TTL 5 +#define NET_DB_TTL 300 #define NETDB_LOW_MARK 900 #define NETDB_HIGH_MARK 1000 @@ -172,16 +172,16 @@ netdbAdd(struct in_addr addr, char *hostname) } static void -netdbSendPing(int fdunused, struct hostent *hp, void *data) +netdbSendPing(int fdunused, ipcache_addrs * ia, void *data) { struct in_addr addr; char *hostname = data; netdbEntry *n; - if (hp == NULL) { + if (ia == NULL) { xfree(hostname); return; } - addr = inaddrFromHostent(hp); + addr = ia->in_addrs[ia->cur]; if ((n = netdbLookupHost(hostname)) == NULL) n = netdbAdd(addr, hostname); debug(37, 3, "netdbSendPing: pinging %s\n", hostname); @@ -296,4 +296,26 @@ netdbHops(struct in_addr addr) } return 256; } + +void +netdbFreeMemory(void) +{ + netdbEntry *e; + netdbEntry **list; + int i = 0; + int j; + list = xcalloc(meta_data.netdb, sizeof(netdbEntry)); + e = (netdbEntry *) hash_first(addr_table); + while (e && i < meta_data.netdb) { + *(list + i) = e; + i++; + e = (netdbEntry *) hash_next(addr_table); + } + for (j = 0; j < i; j++) + xfree(*(list + j)); + xfree(list); + hashFreeMemory(addr_table); + hashFreeMemory(host_table); +} + #endif /* USE_ICMP */ diff --git a/src/redirect.cc b/src/redirect.cc index 8439926086..5032e382a2 100644 --- a/src/redirect.cc +++ b/src/redirect.cc @@ -1,5 +1,5 @@ /* - * $Id: redirect.cc,v 1.22 1996/10/09 15:34:35 wessels Exp $ + * $Id: redirect.cc,v 1.23 1996/10/09 22:49:41 wessels Exp $ * * DEBUG: section 29 Redirector * AUTHOR: Duane Wessels @@ -88,7 +88,6 @@ static int redirectCreateRedirector(char *command) { int pid; - u_short port; struct sockaddr_in S; static int n_redirector = 0; int cfd; @@ -113,7 +112,6 @@ redirectCreateRedirector(char *command) comm_close(cfd); return -1; } - port = ntohs(S.sin_port); listen(cfd, 1); if ((pid = fork()) < 0) { debug(29, 0, "redirect_create_redirector: fork: %s\n", xstrerror()); @@ -131,7 +129,7 @@ redirectCreateRedirector(char *command) NULL); /* blocking! */ if (sfd == COMM_ERROR) return -1; - if (comm_connect(sfd, localhost, port) == COMM_ERROR) { + if (comm_connect_addr(sfd, &S) == COMM_ERROR) { comm_close(sfd); return -1; } diff --git a/src/send-announce.cc b/src/send-announce.cc index 5fe8804210..495e492a11 100644 --- a/src/send-announce.cc +++ b/src/send-announce.cc @@ -1,6 +1,6 @@ /* - * $Id: send-announce.cc,v 1.19 1996/09/17 02:30:02 wessels Exp $ + * $Id: send-announce.cc,v 1.20 1996/10/09 22:49:42 wessels Exp $ * * DEBUG: section 27 Cache Announcer * AUTHOR: Duane Wessels @@ -37,7 +37,7 @@ send_announce(void) LOCAL_ARRAY(char, tbuf, 256); LOCAL_ARRAY(char, sndbuf, BUFSIZ); icpUdpData *qdata = NULL; - struct hostent *hp = NULL; + ipcache_addrs *ia = NULL; char *host = NULL; char *file = NULL; u_short port; @@ -48,7 +48,7 @@ send_announce(void) host = Config.Announce.host; port = Config.Announce.port; - if ((hp = ipcache_gethostbyname(host, IP_BLOCKING_LOOKUP)) == NULL) { + if ((ia = ipcache_gethostbyname(host, IP_BLOCKING_LOOKUP)) == NULL) { debug(27, 1, "send_announce: Unknown host '%s'\n", host); return; } @@ -84,7 +84,7 @@ send_announce(void) qdata->len = strlen(sndbuf) + 1; qdata->address.sin_family = AF_INET; qdata->address.sin_port = htons(port); - qdata->address.sin_addr = inaddrFromHostent(hp); + qdata->address.sin_addr = ia->in_addrs[0]; AppendUdp(qdata); comm_set_select_handler(theOutIcpConnection, COMM_SELECT_WRITE, diff --git a/src/ssl.cc b/src/ssl.cc index 2351d4fb58..a3c114ff35 100644 --- a/src/ssl.cc +++ b/src/ssl.cc @@ -1,6 +1,6 @@ /* - * $Id: ssl.cc,v 1.18 1996/09/20 06:29:07 wessels Exp $ + * $Id: ssl.cc,v 1.19 1996/10/09 22:49:42 wessels Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -45,6 +45,7 @@ typedef struct { } client, server; time_t timeout; int *size_ptr; /* pointer to size in an icpStateData for logging */ + ConnectStateData connectState; } SslStateData; static char conn_established[] = "HTTP/1.0 200 Connection established\r\n\r\n"; @@ -57,11 +58,11 @@ static void sslWriteServer _PARAMS((int fd, SslStateData * sslState)); static void sslWriteClient _PARAMS((int fd, SslStateData * sslState)); static void sslConnected _PARAMS((int fd, SslStateData * sslState)); static void sslProxyConnected _PARAMS((int fd, SslStateData * sslState)); -static void sslConnect _PARAMS((int fd, struct hostent *, void *)); -static void sslConnInProgress _PARAMS((int fd, SslStateData * sslState)); +static void sslConnect _PARAMS((int fd, ipcache_addrs *, void *)); static void sslErrorComplete _PARAMS((int, char *, int, int, void *)); static void sslClose _PARAMS((SslStateData * sslState)); static int sslClientClosed _PARAMS((int fd, SslStateData * sslState)); +static void sslConnectDone _PARAMS((int fd, int status, void *data)); static void sslClose(SslStateData * sslState) @@ -302,58 +303,12 @@ sslErrorComplete(int fd, char *buf, int size, int errflag, void *sslState) static void -sslConnInProgress(int fd, SslStateData * sslState) -{ - char *buf = NULL; - debug(26, 5, "sslConnInProgress: FD %d sslState=%p\n", fd, sslState); - - if (comm_connect(fd, sslState->host, sslState->port) != COMM_OK) { - debug(26, 5, "sslConnInProgress: FD %d: %s\n", fd, xstrerror()); - switch (errno) { -#if EINPROGRESS != EALREADY - case EINPROGRESS: -#endif - case EALREADY: - /* We are not connected yet. schedule this handler again */ - comm_set_select_handler(fd, COMM_SELECT_WRITE, - (PF) sslConnInProgress, - (void *) sslState); - return; - default: - buf = squid_error_url(sslState->url, - METHOD_CONNECT, - ERR_CONNECT_FAIL, - NULL, - 500, - xstrerror()); - comm_write(sslState->client.fd, - xstrdup(buf), - strlen(buf), - 30, - sslErrorComplete, - sslState, - xfree); - return; - } - } - if (opt_no_ipcache) - ipcacheInvalidate(sslState->host); - /* We are now fully connected */ - if (Config.sslProxy.host) - sslProxyConnected(fd, sslState); - else - sslConnected(fd, sslState); - return; -} - -static void -sslConnect(int fd, struct hostent *hp, void *data) +sslConnect(int fd, ipcache_addrs * ia, void *data) { SslStateData *sslState = data; request_t *request = sslState->request; - int status; char *buf = NULL; - if (!ipcache_gethostbyname(sslState->host, 0)) { + if (ia == NULL) { debug(26, 4, "sslConnect: Unknown host: %s\n", sslState->host); buf = squid_error_url(sslState->url, request->method, @@ -386,32 +341,34 @@ sslConnect(int fd, struct hostent *hp, void *data) COMM_SELECT_LIFETIME, (PF) sslLifetimeExpire, (void *) sslState); - /* Open connection. */ - if ((status = comm_connect(fd, sslState->host, sslState->port))) { - if (status != EINPROGRESS) { - buf = squid_error_url(sslState->url, - request->method, - ERR_CONNECT_FAIL, - fd_table[fd].ipaddr, - 500, - xstrerror()); - comm_write(sslState->client.fd, - xstrdup(buf), - strlen(buf), - 30, - sslErrorComplete, - (void *) sslState, - xfree); - return; - } else { - debug(26, 5, "sslConnect: conn %d EINPROGRESS\n", fd); - /* The connection is in progress, install ssl handler */ - comm_set_select_handler(sslState->server.fd, - COMM_SELECT_WRITE, - (PF) sslConnInProgress, - (void *) sslState); - return; - } + sslState->connectState.fd = fd; + sslState->connectState.host = sslState->host; + sslState->connectState.port = sslState->port; + sslState->connectState.handler = sslConnectDone; + sslState->connectState.data = sslState; + comm_nbconnect(fd, &sslState->connectState); +} + +static void +sslConnectDone(int fd, int status, void *data) +{ + SslStateData *sslState = data; + char *buf = NULL; + if (status == COMM_ERROR) { + buf = squid_error_url(sslState->url, + sslState->request->method, + ERR_CONNECT_FAIL, + fd_table[fd].ipaddr, + 500, + xstrerror()); + comm_write(sslState->client.fd, + xstrdup(buf), + strlen(buf), + 30, + sslErrorComplete, + (void *) sslState, + xfree); + return; } if (opt_no_ipcache) ipcacheInvalidate(sslState->host); diff --git a/src/stat.cc b/src/stat.cc index 77ccd751ca..dc2ad4c2a6 100644 --- a/src/stat.cc +++ b/src/stat.cc @@ -1,5 +1,6 @@ + /* - * $Id: stat.cc,v 1.79 1996/10/09 15:34:37 wessels Exp $ + * $Id: stat.cc,v 1.80 1996/10/09 22:49:43 wessels Exp $ * * DEBUG: section 18 Cache Manager Statistics * AUTHOR: Harvest Derived @@ -667,7 +668,7 @@ static void info_get(cacheinfo * obj, StoreEntry * sentry) { char *tod = NULL; - time_t f; + float f; #if HAVE_MALLINFO int t; #endif @@ -694,7 +695,7 @@ info_get(cacheinfo * obj, StoreEntry * sentry) storeAppendPrintf(sentry, "{\tNumber of UDP connections:\t%lu}\n", nudpconn); - f = squid_curtime - squid_starttime; + f = (float) (squid_curtime - squid_starttime); storeAppendPrintf(sentry, "{\tConnections per hour:\t%.1f}\n", f == 0.0 ? 0.0 : ((ntcpconn + nudpconn) / (f / 3600))); diff --git a/src/tools.cc b/src/tools.cc index e23570a1d6..fef61fda04 100644 --- a/src/tools.cc +++ b/src/tools.cc @@ -1,6 +1,6 @@ /* - * $Id: tools.cc,v 1.67 1996/10/09 15:34:41 wessels Exp $ + * $Id: tools.cc,v 1.68 1996/10/09 22:49:44 wessels Exp $ * * DEBUG: section 21 Misc Functions * AUTHOR: Harvest Derived @@ -308,6 +308,7 @@ normal_shutdown(void) fdstatFreeMemory(); errorpageFreeMemory(); stmemFreeMemory(); + netdbFreeMemory(); debug(21, 0, "Squid Cache (Version %s): Exiting normally.\n", version_string); exit(0); @@ -399,7 +400,7 @@ getMyHostname(void) xstrerror()); return NULL; } else { - if ((h = ipcache_gethostbyname(host, IP_BLOCKING_LOOKUP)) != NULL) { + if ((h = gethostbyname(host)) != NULL) { /* DNS lookup successful */ /* use the official name from DNS lookup */ strcpy(host, h->h_name); diff --git a/src/tunnel.cc b/src/tunnel.cc index cd92e41c90..ddddbc8053 100644 --- a/src/tunnel.cc +++ b/src/tunnel.cc @@ -1,6 +1,6 @@ /* - * $Id: tunnel.cc,v 1.18 1996/09/20 06:29:07 wessels Exp $ + * $Id: tunnel.cc,v 1.19 1996/10/09 22:49:42 wessels Exp $ * * DEBUG: section 26 Secure Sockets Layer Proxy * AUTHOR: Duane Wessels @@ -45,6 +45,7 @@ typedef struct { } client, server; time_t timeout; int *size_ptr; /* pointer to size in an icpStateData for logging */ + ConnectStateData connectState; } SslStateData; static char conn_established[] = "HTTP/1.0 200 Connection established\r\n\r\n"; @@ -57,11 +58,11 @@ static void sslWriteServer _PARAMS((int fd, SslStateData * sslState)); static void sslWriteClient _PARAMS((int fd, SslStateData * sslState)); static void sslConnected _PARAMS((int fd, SslStateData * sslState)); static void sslProxyConnected _PARAMS((int fd, SslStateData * sslState)); -static void sslConnect _PARAMS((int fd, struct hostent *, void *)); -static void sslConnInProgress _PARAMS((int fd, SslStateData * sslState)); +static void sslConnect _PARAMS((int fd, ipcache_addrs *, void *)); static void sslErrorComplete _PARAMS((int, char *, int, int, void *)); static void sslClose _PARAMS((SslStateData * sslState)); static int sslClientClosed _PARAMS((int fd, SslStateData * sslState)); +static void sslConnectDone _PARAMS((int fd, int status, void *data)); static void sslClose(SslStateData * sslState) @@ -302,58 +303,12 @@ sslErrorComplete(int fd, char *buf, int size, int errflag, void *sslState) static void -sslConnInProgress(int fd, SslStateData * sslState) -{ - char *buf = NULL; - debug(26, 5, "sslConnInProgress: FD %d sslState=%p\n", fd, sslState); - - if (comm_connect(fd, sslState->host, sslState->port) != COMM_OK) { - debug(26, 5, "sslConnInProgress: FD %d: %s\n", fd, xstrerror()); - switch (errno) { -#if EINPROGRESS != EALREADY - case EINPROGRESS: -#endif - case EALREADY: - /* We are not connected yet. schedule this handler again */ - comm_set_select_handler(fd, COMM_SELECT_WRITE, - (PF) sslConnInProgress, - (void *) sslState); - return; - default: - buf = squid_error_url(sslState->url, - METHOD_CONNECT, - ERR_CONNECT_FAIL, - NULL, - 500, - xstrerror()); - comm_write(sslState->client.fd, - xstrdup(buf), - strlen(buf), - 30, - sslErrorComplete, - sslState, - xfree); - return; - } - } - if (opt_no_ipcache) - ipcacheInvalidate(sslState->host); - /* We are now fully connected */ - if (Config.sslProxy.host) - sslProxyConnected(fd, sslState); - else - sslConnected(fd, sslState); - return; -} - -static void -sslConnect(int fd, struct hostent *hp, void *data) +sslConnect(int fd, ipcache_addrs * ia, void *data) { SslStateData *sslState = data; request_t *request = sslState->request; - int status; char *buf = NULL; - if (!ipcache_gethostbyname(sslState->host, 0)) { + if (ia == NULL) { debug(26, 4, "sslConnect: Unknown host: %s\n", sslState->host); buf = squid_error_url(sslState->url, request->method, @@ -386,32 +341,34 @@ sslConnect(int fd, struct hostent *hp, void *data) COMM_SELECT_LIFETIME, (PF) sslLifetimeExpire, (void *) sslState); - /* Open connection. */ - if ((status = comm_connect(fd, sslState->host, sslState->port))) { - if (status != EINPROGRESS) { - buf = squid_error_url(sslState->url, - request->method, - ERR_CONNECT_FAIL, - fd_table[fd].ipaddr, - 500, - xstrerror()); - comm_write(sslState->client.fd, - xstrdup(buf), - strlen(buf), - 30, - sslErrorComplete, - (void *) sslState, - xfree); - return; - } else { - debug(26, 5, "sslConnect: conn %d EINPROGRESS\n", fd); - /* The connection is in progress, install ssl handler */ - comm_set_select_handler(sslState->server.fd, - COMM_SELECT_WRITE, - (PF) sslConnInProgress, - (void *) sslState); - return; - } + sslState->connectState.fd = fd; + sslState->connectState.host = sslState->host; + sslState->connectState.port = sslState->port; + sslState->connectState.handler = sslConnectDone; + sslState->connectState.data = sslState; + comm_nbconnect(fd, &sslState->connectState); +} + +static void +sslConnectDone(int fd, int status, void *data) +{ + SslStateData *sslState = data; + char *buf = NULL; + if (status == COMM_ERROR) { + buf = squid_error_url(sslState->url, + sslState->request->method, + ERR_CONNECT_FAIL, + fd_table[fd].ipaddr, + 500, + xstrerror()); + comm_write(sslState->client.fd, + xstrdup(buf), + strlen(buf), + 30, + sslErrorComplete, + (void *) sslState, + xfree); + return; } if (opt_no_ipcache) ipcacheInvalidate(sslState->host); diff --git a/src/wais.cc b/src/wais.cc index 260c005adb..4a3174fea2 100644 --- a/src/wais.cc +++ b/src/wais.cc @@ -1,6 +1,6 @@ /* - * $Id: wais.cc,v 1.44 1996/09/20 06:29:19 wessels Exp $ + * $Id: wais.cc,v 1.45 1996/10/09 22:49:45 wessels Exp $ * * DEBUG: section 24 WAIS Relay * AUTHOR: Harvest Derived @@ -116,6 +116,7 @@ typedef struct { int relayport; char *mime_hdr; char request[MAX_URL + 1]; + ConnectStateData connectState; } WaisStateData; static int waisStateFree _PARAMS((int, WaisStateData *)); @@ -124,8 +125,8 @@ static void waisLifetimeExpire _PARAMS((int, WaisStateData *)); static void waisReadReply _PARAMS((int, WaisStateData *)); static void waisSendComplete _PARAMS((int, char *, int, int, void *)); static void waisSendRequest _PARAMS((int, WaisStateData *)); -static void waisConnInProgress _PARAMS((int, WaisStateData *)); -static void waisConnect _PARAMS((int, struct hostent *, void *)); +static void waisConnect _PARAMS((int, ipcache_addrs *, void *)); +static void waisConnectDone _PARAMS((int fd, int status, void *data)); static int waisStateFree(int fd, WaisStateData * waisState) @@ -341,37 +342,6 @@ waisSendRequest(int fd, WaisStateData * waisState) storeSetPublicKey(waisState->entry); /* Make it public */ } -static void -waisConnInProgress(int fd, WaisStateData * waisState) -{ - StoreEntry *entry = waisState->entry; - - debug(11, 5, "waisConnInProgress: FD %d waisState=%p\n", fd, waisState); - - if (comm_connect(fd, waisState->relayhost, waisState->relayport) != COMM_OK) { - debug(11, 5, "waisConnInProgress: FD %d: %s\n", fd, xstrerror()); - switch (errno) { - case EINPROGRESS: - case EALREADY: - /* schedule this handler again */ - comm_set_select_handler(fd, - COMM_SELECT_WRITE, - (PF) waisConnInProgress, - (void *) waisState); - return; - default: - squid_error_entry(entry, ERR_CONNECT_FAIL, xstrerror()); - comm_close(fd); - return; - } - } - /* Call the real write handler, now that we're fully connected */ - if (opt_no_ipcache) - ipcacheInvalidate(waisState->relayhost); - comm_set_select_handler(fd, COMM_SELECT_WRITE, - (PF) waisSendRequest, (void *) waisState); -} - int waisStart(int unusedfd, char *url, method_t method, char *mime_hdr, StoreEntry * entry) { @@ -416,40 +386,35 @@ waisStart(int unusedfd, char *url, method_t method, char *mime_hdr, StoreEntry * static void -waisConnect(int fd, struct hostent *hp, void *data) +waisConnect(int fd, ipcache_addrs * ia, void *data) { - int status; WaisStateData *waisState = data; - char *host = waisState->relayhost; - u_short port = waisState->relayport; 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; } - /* Open connection. */ - if ((status = comm_connect(fd, host, port))) { - if (status != EINPROGRESS) { - squid_error_entry(waisState->entry, ERR_CONNECT_FAIL, xstrerror()); - comm_close(fd); - return; - } else { - debug(24, 5, "waisStart: FD %d EINPROGRESS\n", fd); - comm_set_select_handler(fd, - COMM_SELECT_LIFETIME, - (PF) waisLifetimeExpire, - (void *) waisState); - comm_set_select_handler(fd, - COMM_SELECT_WRITE, - (PF) waisConnInProgress, - (void *) waisState); - return; - } + waisState->connectState.fd = fd; + waisState->connectState.host = waisState->relayhost; + waisState->connectState.port = waisState->relayport; + waisState->connectState.handler = waisConnectDone; + waisState->connectState.data = waisState; + comm_nbconnect(fd, &waisState->connectState); +} + +static void +waisConnectDone(int fd, int status, void *data) +{ + WaisStateData *waisState = data; + if (status == COMM_ERROR) { + squid_error_entry(waisState->entry, ERR_CONNECT_FAIL, xstrerror()); + comm_close(fd); + return; } /* Install connection complete handler. */ if (opt_no_ipcache) - ipcacheInvalidate(host); + ipcacheInvalidate(waisState->relayhost); comm_set_select_handler(fd, COMM_SELECT_LIFETIME, (PF) waisLifetimeExpire,