void helperStatefulSubmit(statefulhelper * hlp, const char *buf, HLPSCB * callback, void *data, helper_stateful_server * srv) { helper_stateful_request *r = memAllocate(MEM_HELPER_STATEFUL_REQUEST); if (hlp == NULL) { debug(84, 3) ("helperStatefulSubmit: hlp == NULL\n"); callback(data, 0, NULL); return; } r->callback = callback; r->data = data; if (buf) r->buf = xstrdup(buf); cbdataLock(r->data); if (!srv) srv = helperStatefulGetServer(hlp); if (srv) { debug(84, 5) ("helperStatefulSubmit: sever %p, buf '%s'.\n", srv, buf ? buf : "NULL"); assert(!srv->request); assert(!srv->flags.busy); helperStatefulDispatch(srv, r); } else { debug(84, 9) ("helperStatefulSubmit: enqueued, buf '%s'.\n", buf ? buf : "NULL"); StatefulEnqueue(hlp, r); } }
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 netdbBinaryExchange(StoreEntry * s) { http_reply *reply = s->mem_obj->reply; #if USE_ICMP netdbEntry *n; int i; int j; int rec_sz; char *buf; struct in_addr addr; storeBuffer(s); httpReplyReset(reply); httpReplySetHeaders(reply, HTTP_OK, "OK", NULL, -1, squid_curtime, -1); httpReplySwapOut(reply, s); rec_sz = 0; rec_sz += 1 + sizeof(addr.s_addr); rec_sz += 1 + sizeof(int); rec_sz += 1 + sizeof(int); buf = memAllocate(MEM_4K_BUF); i = 0; hash_first(addr_table); while ((n = (netdbEntry *) hash_next(addr_table))) { if (0.0 == n->rtt) continue; if (n->rtt > 60000) /* RTT > 1 MIN probably bogus */ continue; if (!safe_inet_addr(n->network, &addr)) continue; buf[i++] = (char) NETDB_EX_NETWORK; xmemcpy(&buf[i], &addr.s_addr, sizeof(addr.s_addr)); i += sizeof(addr.s_addr); buf[i++] = (char) NETDB_EX_RTT; j = htonl((int) (n->rtt * 1000)); xmemcpy(&buf[i], &j, sizeof(int)); i += sizeof(int); buf[i++] = (char) NETDB_EX_HOPS; j = htonl((int) (n->hops * 1000)); xmemcpy(&buf[i], &j, sizeof(int)); i += sizeof(int); if (i + rec_sz > 4096) { storeAppend(s, buf, i); i = 0; } } if (i > 0) { storeAppend(s, buf, i); i = 0; } assert(0 == i); storeBufferFlush(s); memFree(buf, MEM_4K_BUF); #else httpReplyReset(reply); httpReplySetHeaders(reply, HTTP_BAD_REQUEST, "Bad Request", NULL, -1, -1, -1); httpReplySwapOut(reply, s); storeAppendPrintf(s, "NETDB support not compiled into this Squid cache.\n"); #endif storeComplete(s); }
const cache_key * storeKeyDup(const cache_key * key) { cache_key *dup = memAllocate(MEM_MD5_DIGEST); xmemcpy(dup, key, MD5_DIGEST_CHARS); return dup; }
static void asnCacheStart(int as) { LOCAL_ARRAY(char, asres, 4096); StoreEntry *e; request_t *req; ASState *asState; 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, 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; storeClientCopy(asState->sc, e, asState->seen, asState->offset, 4096, memAllocate(MEM_4K_BUF), asHandleReply, asState); }
void netdbExchangeStart(void *data) { #if USE_ICMP peer *p = data; char *uri; netdbExchangeState *ex; CBDATA_INIT_TYPE(netdbExchangeState); ex = cbdataAlloc(netdbExchangeState); cbdataLock(p); ex->p = p; uri = internalRemoteUri(p->host, p->http_port, "/squid-internal-dynamic/", "netdb"); debug(38, 3) ("netdbExchangeStart: Requesting '%s'\n", uri); assert(NULL != uri); ex->r = urlParse(METHOD_GET, uri); if (NULL == ex->r) { debug(38, 1) ("netdbExchangeStart: Bad URI %s\n", uri); return; } requestLink(ex->r); assert(NULL != ex->r); httpBuildVersion(&ex->r->http_ver, 1, 0); ex->e = storeCreateEntry(uri, uri, null_request_flags, METHOD_GET); ex->buf_sz = 4096; ex->buf = memAllocate(MEM_4K_BUF); assert(NULL != ex->e); ex->sc = storeClientRegister(ex->e, ex); storeClientCopy(ex->sc, ex->e, ex->seen, ex->used, ex->buf_sz, ex->buf, netdbExchangeHandleReply, ex); ex->r->flags.loopdetect = 1; /* cheat! -- force direct */ if (p->login) xstrncpy(ex->r->login, p->login, MAX_LOGIN_SZ); fwdStart(-1, ex->e, ex->r); #endif }
/* add client with fd to client list */ void storeClientListAdd(StoreEntry * e, void *data) { MemObject *mem = e->mem_obj; store_client **T; store_client *sc; assert(mem); if (storeClientListSearch(mem, data) != NULL) return; e->refcount++; mem->nclients++; sc = memAllocate(MEM_STORE_CLIENT); cbdataAdd(sc, memFree, MEM_STORE_CLIENT); /* sc is callback_data for file_read */ cbdataLock(data); /* locked while we point to it */ sc->callback_data = data; sc->seen_offset = 0; sc->copy_offset = 0; sc->flags.disk_io_pending = 0; sc->entry = e; sc->type = storeClientType(e); if (sc->type == STORE_DISK_CLIENT) /* assert we'll be able to get the data we want */ /* maybe we should open swapin_fd here */ assert(e->swap_file_number > -1 || storeSwapOutAble(e)); for (T = &mem->clients; *T; T = &(*T)->next); *T = sc; #if DELAY_POOLS sc->delay_id = 0; #endif }
HttpHdrRange * httpHdrRangeCreate(void) { HttpHdrRange *r = memAllocate(MEM_HTTP_HDR_RANGE); stackInit(&r->specs); return r; }
HttpReply * httpReplyCreate(void) { HttpReply *rep = memAllocate(MEM_HTTP_REPLY); debug(58, 7) ("creating rep: %p\n", rep); httpReplyInit(rep); return rep; }
HttpHdrContRange * httpHdrContRangeCreate(void) { HttpHdrContRange *r = memAllocate(MEM_HTTP_HDR_CONTENT_RANGE); r->spec.offset = r->spec.length = range_spec_unknown; r->elength = range_spec_unknown; return r; }
CacheDigest * cacheDigestCreate(int capacity, int bpe) { CacheDigest *cd = memAllocate(MEM_CACHE_DIGEST); assert(SQUID_MD5_DIGEST_LENGTH == 16); /* our hash functions rely on 16 byte keys */ cacheDigestInit(cd, capacity, bpe); return cd; }
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); }
void stmemNodeRefCreate(mem_node_ref * r) { assert(r->node == NULL); r->node = memAllocate(MEM_MEM_NODE); r->node->uses = 0; r->node->next = NULL; r->node->len = 4096; r->offset = 0; }
/* parses and inits header entry, returns new entry on success */ static HttpHeaderEntry * httpHeaderEntryParseCreate(const char *field_start, const char *field_end) { HttpHeaderEntry *e; int id; /* note: name_start == field_start */ const char *name_end = strchr(field_start, ':'); const int name_len = name_end ? name_end - field_start : 0; const char *value_start = field_start + name_len + 1; /* skip ':' */ /* note: value_end == field_end */ HeaderEntryParsedCount++; /* do we have a valid field name within this field? */ if (!name_len || name_end > field_end) return NULL; if (name_len > 65536) { /* String has a 64K limit */ debug(55, 1) ("WARNING: ignoring header name of %d bytes\n", name_len); return NULL; } /* now we know we can parse it */ e = memAllocate(MEM_HTTP_HDR_ENTRY); debug(55, 9) ("creating entry %p: near '%s'\n", e, getStringPrefix(field_start, field_end)); /* is it a "known" field? */ id = httpHeaderIdByName(field_start, name_len, Headers, HDR_ENUM_END); if (id < 0) id = HDR_OTHER; assert_eid(id); e->id = id; /* set field name */ if (id == HDR_OTHER) stringLimitInit(&e->name, field_start, name_len); else e->name = Headers[id].name; /* trim field value */ while (value_start < field_end && xisspace(*value_start)) value_start++; if (field_end - value_start > 65536) { /* String has a 64K limit */ debug(55, 1) ("WARNING: ignoring '%s' header of %d bytes\n", strBuf(e->name), (int) (field_end - value_start)); if (e->id == HDR_OTHER) stringClean(&e->name); memFree(e, MEM_HTTP_HDR_ENTRY); return NULL; } /* set field value */ stringLimitInit(&e->value, value_start, field_end - value_start); Headers[id].stat.seenCount++; Headers[id].stat.aliveCount++; debug(55, 9) ("created entry %p: '%s: %s'\n", e, strBuf(e->name), strBuf(e->value)); return e; }
static ClientInfo * clientdbAdd(struct in_addr addr) { ClientInfo *c; c = memAllocate(MEM_CLIENT_INFO); c->hash.key = xstrdup(inet_ntoa(addr)); c->addr = addr; hash_join(client_table, &c->hash); statCounter.client_http.clients++; return c; }
static netdbEntry * netdbAdd(struct in_addr addr) { netdbEntry *n; if (memInUse(MEM_NETDBENTRY) > Config.Netdb.high) netdbPurgeLRU(); if ((n = netdbLookupAddr(addr)) == NULL) { n = memAllocate(MEM_NETDBENTRY); netdbHashInsert(n, addr); } return n; }
static void netdbHostInsert(netdbEntry * n, const char *hostname) { net_db_name *x = memAllocate(MEM_NET_DB_NAME); x->hash.key = xstrdup(hostname); x->next = n->hosts; n->hosts = x; x->net_db_entry = n; assert(hash_lookup(host_table, hostname) == NULL); hash_join(host_table, &x->hash); n->link_count++; }
/* UserNameCacheAdd: add a auth_user structure to the username cache */ void authenticateUserNameCacheAdd(auth_user_t * auth_user) { auth_user_hash_pointer *usernamehash; usernamehash = memAllocate(MEM_AUTH_USER_HASH); usernamehash->key = authenticateUserUsername(auth_user); usernamehash->auth_user = auth_user; hash_join(proxy_auth_username_cache, (hash_link *) usernamehash); auth_user->usernamehash = usernamehash; /* lock for presence in the cache */ authenticateAuthUserLock(auth_user); }
/* allocate a variable size buffer using best-fit pool */ void * memAllocBuf(size_t net_size, size_t * gross_size) { mem_type type = memFindBufSizeType(net_size, gross_size); if (type != MEM_NONE) return memAllocate(type); else { memMeterInc(HugeBufCountMeter); memMeterAdd(HugeBufVolumeMeter, *gross_size); return xcalloc(1, net_size); } }
/* allocate new peer digest, call Init, and lock everything */ PeerDigest * peerDigestCreate(peer * p) { PeerDigest *pd; assert(p); pd = memAllocate(MEM_PEER_DIGEST); cbdataAdd(pd, memFree, MEM_PEER_DIGEST); peerDigestInit(pd, p); cbdataLock(pd->peer); /* we will use the peer */ return pd; }
auth_user_t * authenticateAuthUserNew(const char *scheme) { auth_user_t *temp_auth; temp_auth = memAllocate(MEM_AUTH_USER_T); assert(temp_auth != NULL); memset(temp_auth, '\0', sizeof(auth_user_t)); temp_auth->auth_type = AUTH_UNKNOWN; temp_auth->references = 0; temp_auth->auth_module = authenticateAuthSchemeId(scheme) + 1; temp_auth->usernamehash = NULL; return temp_auth; }
static void whoisReadReply(int fd, void *data) { WhoisState *p = data; StoreEntry *entry = p->entry; char *buf = memAllocate(MEM_4K_BUF); MemObject *mem = entry->mem_obj; int len; statCounter.syscalls.sock.reads++; len = FD_READ_METHOD(fd, buf, 4095); buf[len] = '\0'; debug(75, 3) ("whoisReadReply: FD %d read %d bytes\n", fd, len); debug(75, 5) ("{%s}\n", buf); if (len > 0) { if (0 == mem->inmem_hi) { http_reply *reply = mem->reply; http_version_t version; storeBuffer(entry); httpBuildVersion(&version, 1, 0); httpReplySetHeaders(reply, version, HTTP_OK, "Gatewaying", "text/plain", -1, -1, -2); httpReplySwapOut(reply, entry); } fd_bytes(fd, len, FD_READ); kb_incr(&statCounter.server.all.kbytes_in, len); kb_incr(&statCounter.server.http.kbytes_in, len); storeAppend(entry, buf, len); storeBufferFlush(entry); commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read); } else if (len < 0) { debug(50, 2) ("whoisReadReply: FD %d: read failure: %s.\n", fd, xstrerror()); if (ignoreErrno(errno)) { commSetSelect(fd, COMM_SELECT_READ, whoisReadReply, p, Config.Timeout.read); } else { ErrorState *err; err = errorCon(ERR_READ_ERROR, HTTP_INTERNAL_SERVER_ERROR, p->fwd->request); err->xerrno = errno; fwdFail(p->fwd, err); comm_close(fd); } } else { storeTimestampsSet(entry); storeBufferFlush(entry); if (!EBIT_TEST(entry->flags, RELEASE_REQUEST)) storeSetPublicKey(entry); fwdComplete(p->fwd); debug(75, 3) ("whoisReadReply: Done: %s\n", storeUrl(entry)); comm_close(fd); } memFree(buf, MEM_4K_BUF); }
void idnsALookup(const char *name, IDNSCB * callback, void *data) { idns_query *q = memAllocate(MEM_IDNS_QUERY); q->sz = sizeof(q->buf); q->id = rfc1035BuildAQuery(name, q->buf, &q->sz); debug(78, 3) ("idnsALookup: buf is %d bytes for %s, id = %#hx\n", (int) q->sz, name, q->id); q->callback = callback; q->callback_data = data; cbdataLock(q->callback_data); q->start_t = current_time; idnsSendQuery(q); }
void idnsPTRLookup(const struct in_addr addr, IDNSCB * callback, void *data) { idns_query *q = memAllocate(MEM_IDNS_QUERY); q->sz = sizeof(q->buf); q->id = rfc1035BuildPTRQuery(addr, q->buf, &q->sz); debug(78, 3) ("idnsPTRLookup: buf is %d bytes for %s, id = %#hx\n", (int) q->sz, inet_ntoa(addr), q->id); q->callback = callback; q->callback_data = data; cbdataLock(q->callback_data); q->start_t = current_time; idnsSendQuery(q); }
request_t * requestCreate(method_t method, protocol_t protocol, const char *urlpath) { request_t *req = memAllocate(MEM_REQUEST_T); req->method = method; req->protocol = protocol; if (urlpath) stringReset(&req->urlpath, urlpath); req->max_forwards = -1; req->lastmod = -1; req->client_addr = no_addr; req->my_addr = no_addr; httpHeaderInit(&req->header, hoRequest); return req; }
static ClientInfo * clientdbAdd(struct in_addr addr) { ClientInfo *c; c = memAllocate(MEM_CLIENT_INFO); c->hash.key = xstrdup(xinet_ntoa(addr)); c->addr = addr; hash_join(client_table, &c->hash); statCounter.client_http.clients++; if ((statCounter.client_http.clients > max_clients) && !cleanup_running && cleanup_scheduled < 2) { cleanup_scheduled++; eventAdd("client_db garbage collector", clientdbScheduledGC, NULL, 90, 0); } return c; }
/* buffer must be allocated from the caller. * It must have at least req_len space in there. * call handler when a reading is complete. */ void file_read(int fd, char *buf, size_t req_len, off_t file_offset, DRCB * handler, void *client_data) { dread_ctrl *ctrl_dat; assert(fd >= 0); ctrl_dat = memAllocate(MEM_DREAD_CTRL); ctrl_dat->fd = fd; ctrl_dat->file_offset = file_offset; ctrl_dat->req_len = req_len; ctrl_dat->buf = buf; ctrl_dat->end_of_file = 0; ctrl_dat->handler = handler; ctrl_dat->client_data = client_data; cbdataLock(client_data); diskHandleRead(fd, ctrl_dat); }
static HttpHeaderEntry * httpHeaderEntryCreate(http_hdr_type id, const char *name, const char *value) { HttpHeaderEntry *e; assert_eid(id); e = memAllocate(MEM_HTTP_HDR_ENTRY); e->id = id; if (id != HDR_OTHER) e->name = Headers[id].name; else stringInit(&e->name, name); stringInit(&e->value, value); Headers[id].stat.aliveCount++; debug(55, 9) ("created entry %p: '%s: %s'\n", e, strBuf(e->name), strBuf(e->value)); return e; }
void icmpSourcePing(struct in_addr to, const icp_common_t * header, const char *url) { #if USE_ICMP char *payload; int len; int ulen; debug(37, 3) ("icmpSourcePing: '%s'\n", url); if ((ulen = strlen(url)) > MAX_URL) return; payload = memAllocate(MEM_8K_BUF); len = sizeof(icp_common_t); xmemcpy(payload, header, len); strcpy(payload + len, url); len += ulen + 1; icmpSendEcho(to, S_ICMP_ICP, payload, len); memFree(payload, MEM_8K_BUF); #endif }
/* * This function has the purpose of combining multiple writes. This is * to facilitate the ASYNC_IO option since it can only guarantee 1 * write to a file per trip around the comm.c select() loop. That's bad * because more than 1 write can be made to the access.log file per * trip, and so this code is purely designed to help batch multiple * sequential writes to the access.log file. Squid will never issue * multiple writes for any other file type during 1 trip around the * select() loop. --SLF */ static void diskCombineWrites(struct _fde_disk *fdd) { int len = 0; dwrite_q *q = NULL; dwrite_q *wq = NULL; /* * We need to combine multiple write requests on an FD's write * queue But only if we don't need to seek() in between them, ugh! * XXX This currently ignores any seeks (file_offset) */ if (fdd->write_q != NULL && fdd->write_q->next != NULL) { len = 0; for (q = fdd->write_q; q != NULL; q = q->next) len += q->len - q->buf_offset; wq = memAllocate(MEM_DWRITE_Q); wq->buf = xmalloc(len); wq->len = 0; wq->buf_offset = 0; wq->next = NULL; wq->free_func = xfree; do { q = fdd->write_q; len = q->len - q->buf_offset; xmemcpy(wq->buf + wq->len, q->buf + q->buf_offset, len); wq->len += len; fdd->write_q = q->next; if (q->free_func) (q->free_func) (q->buf); if (q) { memFree(q, MEM_DWRITE_Q); q = NULL; } } while (fdd->write_q != NULL); fdd->write_q_tail = wq; fdd->write_q = wq; } }