static void asnCacheStart(int as) { LOCAL_ARRAY(char, asres, 4096); StoreEntry *e; request_t *req; ASState *asState; method_t *method_get; method_get = urlMethodGetKnownByCode(METHOD_GET); asState = cbdataAlloc(ASState); debug(53, 3) ("asnCacheStart: AS %d\n", as); snprintf(asres, 4096, "whois://%s/!gAS%d", Config.as_whois_server, as); asState->as_number = as; req = urlParse(method_get, asres); assert(NULL != req); asState->request = requestLink(req); if ((e = storeGetPublic(asres, method_get)) == NULL) { e = storeCreateEntry(asres, null_request_flags, method_get); asState->sc = storeClientRegister(e, asState); fwdStart(-1, e, asState->request); } else { storeLockObject(e); asState->sc = storeClientRegister(e, asState); } asState->entry = e; asState->seen = 0; asState->offset = 0; storeClientRef(asState->sc, e, asState->seen, asState->offset, SM_PAGE_SIZE, asHandleReply, asState); }
static void mimeLoadIconFile(const char *icon) { int fd; int n; request_flags flags; struct stat sb; StoreEntry *e; LOCAL_ARRAY(char, path, MAXPATHLEN); LOCAL_ARRAY(char, url, MAX_URL); char *buf; const char *type = mimeGetContentType(icon); HttpReply *reply; if (type == NULL) fatal("Unknown icon format while reading mime.conf\n"); buf = internalLocalUri("/squid-internal-static/icons/", icon); xstrncpy(url, buf, MAX_URL); if (storeGetPublic(url, METHOD_GET)) return; snprintf(path, MAXPATHLEN, "%s/%s", Config.icons.directory, icon); fd = file_open(path, O_RDONLY); if (fd < 0) { debug(25, 0) ("mimeLoadIconFile: %s: %s\n", path, xstrerror()); return; } if (fstat(fd, &sb) < 0) { debug(50, 0) ("mimeLoadIconFile: FD %d: fstat: %s\n", fd, xstrerror()); return; } flags = null_request_flags; flags.cachable = 1; e = storeCreateEntry(url, url, flags, METHOD_GET); assert(e != NULL); storeSetPublicKey(e); storeBuffer(e); e->mem_obj->request = requestLink(urlParse(METHOD_GET, url)); httpReplyReset(reply = e->mem_obj->reply); httpReplySetHeaders(reply, 1.0, HTTP_OK, NULL, type, (int) sb.st_size, sb.st_mtime, -1); reply->cache_control = httpHdrCcCreate(); httpHdrCcSetMaxAge(reply->cache_control, 86400); httpHeaderPutCc(&reply->header, reply->cache_control); httpReplySwapOut(reply, e); reply->hdr_sz = e->mem_obj->inmem_hi; /* yuk */ /* read the file into the buffer and append it to store */ buf = memAllocate(MEM_4K_BUF); while ((n = read(fd, buf, 4096)) > 0) storeAppend(e, buf, n); file_close(fd); EBIT_SET(e->flags, ENTRY_SPECIAL); storeBufferFlush(e); storeComplete(e); storeTimestampsSet(e); debug(25, 3) ("Loaded icon %s\n", url); storeUnlockObject(e); memFree(buf, MEM_4K_BUF); }
void urnStart(request_t * r, StoreEntry * e) { LOCAL_ARRAY(char, urlres, 4096); request_t *urlres_r = NULL; const char *t; char *host; UrnState *urnState; StoreEntry *urlres_e; ErrorState *err; debug(52, 3) ("urnStart: '%s'\n", storeUrl(e)); CBDATA_INIT_TYPE(UrnState); urnState = cbdataAlloc(UrnState); urnState->entry = e; urnState->request = requestLink(r); storeLockObject(urnState->entry); if (strncasecmp(strBuf(r->urlpath), "menu.", 5) == 0) { char *new_path = xstrdup(strBuf(r->urlpath) + 5); urnState->flags.force_menu = 1; stringReset(&r->urlpath, new_path); xfree(new_path); } if ((t = strChr(r->urlpath, ':')) != NULL) { strSet(r->urlpath, t, '\0'); host = xstrdup(strBuf(r->urlpath)); strSet(r->urlpath, t, ':'); } else { host = xstrdup(strBuf(r->urlpath)); } snprintf(urlres, 4096, "http://%s/uri-res/N2L?urn:%s", host, strBuf(r->urlpath)); safe_free(host); urlres_r = urlParse(METHOD_GET, urlres); if (urlres_r == NULL) { debug(52, 3) ("urnStart: Bad uri-res URL %s\n", urlres); err = errorCon(ERR_URN_RESOLVE, HTTP_NOT_FOUND); err->url = xstrdup(urlres); errorAppendEntry(e, err); return; } httpHeaderPutStr(&urlres_r->header, HDR_ACCEPT, "text/plain"); if ((urlres_e = storeGetPublic(urlres, METHOD_GET)) == NULL) { urlres_e = storeCreateEntry(urlres, urlres, null_request_flags, METHOD_GET); urnState->sc = storeClientListAdd(urlres_e, urnState); fwdStart(-1, urlres_e, urlres_r); } else { storeLockObject(urlres_e); urnState->sc = storeClientListAdd(urlres_e, urnState); } urnState->urlres_e = urlres_e; urnState->urlres_r = requestLink(urlres_r); storeClientCopy(urnState->sc, urlres_e, 0, 0, 4096, memAllocate(MEM_4K_BUF), urnHandleReply, urnState); }
static url_entry * urnParseReply(const char *inbuf, method_t m) { char *buf = xstrdup(inbuf); char *token; char *url; char *host; int rtt; url_entry *list; url_entry *old; int n = 32; int i = 0; debug(52, 3) ("urnParseReply\n"); list = xcalloc(n + 1, sizeof(*list)); for (token = strtok(buf, crlf); token; token = strtok(NULL, crlf)) { debug(52, 3) ("urnParseReply: got '%s'\n", token); if (i == n) { old = list; n <<= 2; list = xcalloc(n + 1, sizeof(*list)); xmemcpy(list, old, i * sizeof(*list)); safe_free(old); } url = xstrdup(token); host = urlHostname(url); if (NULL == host) continue; rtt = netdbHostRtt(host); if (0 == rtt) { debug(52, 3) ("urnParseReply: Pinging %s\n", host); netdbPingSite(host); } list[i].url = url; list[i].host = xstrdup(host); list[i].rtt = rtt; list[i].flags.cached = storeGetPublic(url, m) ? 1 : 0; i++; } debug(52, 3) ("urnParseReply: Found %d URLs\n", i); return list; }
static void icpHandleIcpV2(int fd, struct sockaddr_in from, char *buf, int len) { icp_common_t header; StoreEntry *entry = NULL; char *url = NULL; const cache_key *key; request_t *icp_request = NULL; int allow = 0; aclCheck_t checklist; icp_common_t *reply; int src_rtt = 0; u_num32 flags = 0; int rtt = 0; int hops = 0; xmemcpy(&header, buf, sizeof(icp_common_t)); /* * Only these fields need to be converted */ header.length = ntohs(header.length); header.reqnum = ntohl(header.reqnum); header.flags = ntohl(header.flags); header.pad = ntohl(header.pad); /* * Length field should match the number of bytes read */ if (len != header.length) { debug(12, 3) ("icpHandleIcpV2: ICP message is too small\n"); return; } switch (header.opcode) { case ICP_QUERY: /* We have a valid packet */ url = buf + sizeof(icp_common_t) + sizeof(u_num32); if (strpbrk(url, w_space)) { url = rfc1738_escape(url); reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0); icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0); break; } if ((icp_request = urlParse(METHOD_GET, url)) == NULL) { reply = icpCreateMessage(ICP_ERR, 0, url, header.reqnum, 0); icpUdpSend(fd, &from, reply, LOG_UDP_INVALID, 0); break; } memset(&checklist, '\0', sizeof(checklist)); checklist.src_addr = from.sin_addr; checklist.my_addr = no_addr; checklist.request = icp_request; allow = aclCheckFast(Config.accessList.icp, &checklist); if (!allow) { debug(12, 2) ("icpHandleIcpV2: Access Denied for %s by %s.\n", inet_ntoa(from.sin_addr), AclMatchedName); if (clientdbCutoffDenied(from.sin_addr)) { /* * count this DENIED query in the clientdb, even though * we're not sending an ICP reply... */ clientdbUpdate(from.sin_addr, LOG_UDP_DENIED, PROTO_ICP, 0); } else { reply = icpCreateMessage(ICP_DENIED, 0, url, header.reqnum, 0); icpUdpSend(fd, &from, reply, LOG_UDP_DENIED, 0); } break; } if (header.flags & ICP_FLAG_SRC_RTT) { rtt = netdbHostRtt(icp_request->host); hops = netdbHostHops(icp_request->host); src_rtt = ((hops & 0xFFFF) << 16) | (rtt & 0xFFFF); if (rtt) flags |= ICP_FLAG_SRC_RTT; } /* The peer is allowed to use this cache */ entry = storeGetPublic(url, METHOD_GET); debug(12, 5) ("icpHandleIcpV2: OPCODE %s\n", icp_opcode_str[header.opcode]); if (icpCheckUdpHit(entry, icp_request)) { reply = icpCreateMessage(ICP_HIT, flags, url, header.reqnum, src_rtt); icpUdpSend(fd, &from, reply, LOG_UDP_HIT, 0); break; } if (Config.onoff.test_reachability && rtt == 0) { if ((rtt = netdbHostRtt(icp_request->host)) == 0) netdbPingSite(icp_request->host); } /* if store is rebuilding, return a UDP_HIT, but not a MISS */ if (store_dirs_rebuilding && opt_reload_hit_only) { reply = icpCreateMessage(ICP_MISS_NOFETCH, flags, url, header.reqnum, src_rtt); icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0); } else if (hit_only_mode_until > squid_curtime) { reply = icpCreateMessage(ICP_MISS_NOFETCH, flags, url, header.reqnum, src_rtt); icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0); } else if (Config.onoff.test_reachability && rtt == 0) { reply = icpCreateMessage(ICP_MISS_NOFETCH, flags, url, header.reqnum, src_rtt); icpUdpSend(fd, &from, reply, LOG_UDP_MISS_NOFETCH, 0); } else { reply = icpCreateMessage(ICP_MISS, flags, url, header.reqnum, src_rtt); icpUdpSend(fd, &from, reply, LOG_UDP_MISS, 0); } break; case ICP_HIT: #if ALLOW_SOURCE_PING case ICP_SECHO: #endif case ICP_DECHO: case ICP_MISS: case ICP_DENIED: case ICP_MISS_NOFETCH: if (neighbors_do_private_keys && header.reqnum == 0) { debug(12, 0) ("icpHandleIcpV2: Neighbor %s returned reqnum = 0\n", inet_ntoa(from.sin_addr)); debug(12, 0) ("icpHandleIcpV2: Disabling use of private keys\n"); neighbors_do_private_keys = 0; } url = buf + sizeof(icp_common_t); debug(12, 3) ("icpHandleIcpV2: %s from %s for '%s'\n", icp_opcode_str[header.opcode], inet_ntoa(from.sin_addr), url); key = icpGetCacheKey(url, (int) header.reqnum); /* call neighborsUdpAck even if ping_status != PING_WAITING */ neighborsUdpAck(key, &header, &from); break; case ICP_INVALID: case ICP_ERR: break; default: debug(12, 0) ("icpHandleIcpV2: UNKNOWN OPCODE: %d from %s\n", header.opcode, inet_ntoa(from.sin_addr)); break; } if (icp_request) requestDestroy(icp_request); }