⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 htcp.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
	htcpFreeSpecifier(s);	return NULL;    }    buf += o;    sz -= o;    o = htcpUnpackCountstr(buf, sz, &s->uri);    if (o < 0) {	debug(31, 1) ("htcpUnpackSpecifier: failed to unpack URI\n");	htcpFreeSpecifier(s);	return NULL;    }    buf += o;    sz -= o;    o = htcpUnpackCountstr(buf, sz, &s->version);    if (o < 0) {	debug(31, 1) ("htcpUnpackSpecifier: failed to unpack VERSION\n");	htcpFreeSpecifier(s);	return NULL;    }    buf += o;    sz -= o;    o = htcpUnpackCountstr(buf, sz, &s->req_hdrs);    if (o < 0) {	debug(31, 1) ("htcpUnpackSpecifier: failed to unpack REQ-HDRS\n");	htcpFreeSpecifier(s);	return NULL;    }    buf += o;    sz -= o;    debug(31, 3) ("htcpUnpackSpecifier: %d bytes left\n", sz);    return s;}static htcpDetail *htcpUnpackDetail(char *buf, int sz){    htcpDetail *d = xcalloc(1, sizeof(htcpDetail));    int o;    debug(31, 3) ("htcpUnpackDetail: %d bytes\n", (int) sz);    o = htcpUnpackCountstr(buf, sz, &d->resp_hdrs);    if (o < 0) {	debug(31, 1) ("htcpUnpackDetail: failed to unpack RESP_HDRS\n");	htcpFreeDetail(d);	return NULL;    }    buf += o;    sz -= o;    o = htcpUnpackCountstr(buf, sz, &d->entity_hdrs);    if (o < 0) {	debug(31, 1) ("htcpUnpackDetail: failed to unpack ENTITY_HDRS\n");	htcpFreeDetail(d);	return NULL;    }    buf += o;    sz -= o;    o = htcpUnpackCountstr(buf, sz, &d->cache_hdrs);    if (o < 0) {	debug(31, 1) ("htcpUnpackDetail: failed to unpack CACHE_HDRS\n");	htcpFreeDetail(d);	return NULL;    }    buf += o;    sz -= o;    debug(31, 3) ("htcpUnpackDetail: %d bytes left\n", sz);    return d;}static voidhtcpTstReply(htcpDataHeader * dhdr, StoreEntry * e, htcpSpecifier * spec, struct sockaddr_in *from){    htcpStuff stuff;    char *pkt;    HttpHeader hdr;    MemBuf mb;    Packer p;    ssize_t pktlen;    char *host;    int rtt = 0;    int hops = 0;    int samp = 0;    char cto_buf[128];    stuff.op = HTCP_TST;    stuff.rr = RR_RESPONSE;    stuff.f1 = 0;    stuff.response = e ? 0 : 1;    stuff.msg_id = dhdr->msg_id;    if (spec) {	memBufDefInit(&mb);	packerToMemInit(&p, &mb);	httpHeaderInit(&hdr, hoHtcpReply);	stuff.S.method = spec->method;	stuff.S.uri = spec->uri;	stuff.S.version = spec->version;	stuff.S.req_hdrs = spec->req_hdrs;	httpHeaderPutInt(&hdr, HDR_AGE,	    e->timestamp <= squid_curtime ?	    squid_curtime - e->timestamp : 0);	httpHeaderPackInto(&hdr, &p);	stuff.D.resp_hdrs = xstrdup(mb.buf);	debug(31, 3) ("htcpTstReply: resp_hdrs = {%s}\n", stuff.D.resp_hdrs);	memBufReset(&mb);	httpHeaderReset(&hdr);	if (e->expires > -1)	    httpHeaderPutTime(&hdr, HDR_EXPIRES, e->expires);	if (e->lastmod > -1)	    httpHeaderPutTime(&hdr, HDR_LAST_MODIFIED, e->lastmod);	httpHeaderPackInto(&hdr, &p);	stuff.D.entity_hdrs = xstrdup(mb.buf);	debug(31, 3) ("htcpTstReply: entity_hdrs = {%s}\n", stuff.D.entity_hdrs);	memBufReset(&mb);	httpHeaderReset(&hdr);	if ((host = urlHostname(spec->uri))) {	    netdbHostData(host, &samp, &rtt, &hops);	    if (rtt || hops) {		snprintf(cto_buf, 128, "%s %d %f %d",		    host, samp, 0.001 * rtt, hops);		httpHeaderPutExt(&hdr, "Cache-to-Origin", cto_buf);	    }	}	httpHeaderPackInto(&hdr, &p);	stuff.D.cache_hdrs = xstrdup(mb.buf);	debug(31, 3) ("htcpTstReply: cache_hdrs = {%s}\n", stuff.D.cache_hdrs);	memBufClean(&mb);	httpHeaderClean(&hdr);	packerClean(&p);    }    pkt = htcpBuildPacket(&stuff, &pktlen);    if (pkt == NULL) {	debug(31, 0) ("htcpTstReply: htcpBuildPacket() failed\n");	return;    }    htcpSend(pkt, (int) pktlen, from);    xfree(pkt);}static voidhtcpHandleNop(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from){    debug(31, 3) ("htcpHandleNop: Unimplemented\n");}static voidhtcpHandleTst(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from){    debug(31, 3) ("htcpHandleTst: sz = %d\n", (int) sz);    if (hdr->RR == RR_REQUEST)	htcpHandleTstRequest(hdr, buf, sz, from);    else	htcpHandleTstResponse(hdr, buf, sz, from);}static voidhtcpHandleTstResponse(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from){    htcpReplyData htcpReply;    cache_key *key = NULL;    htcpDetail *d = NULL;    char *t;    if (hdr->F1 == 1) {	debug(31, 1) ("htcpHandleTstResponse: error condition, F1/MO == 1\n");	return;    }    memset(&htcpReply, '\0', sizeof(htcpReply));    httpHeaderInit(&htcpReply.hdr, hoHtcpReply);    htcpReply.msg_id = hdr->msg_id;    debug(31, 3) ("htcpHandleTstResponse: msg_id = %d\n", (int) htcpReply.msg_id);    htcpReply.hit = hdr->response ? 0 : 1;    if (hdr->F1) {	debug(31, 3) ("htcpHandleTstResponse: MISS\n");    } else {	debug(31, 3) ("htcpHandleTstResponse: HIT\n");	d = htcpUnpackDetail(buf, sz);	if (d == NULL) {	    debug(31, 1) ("htcpHandleTstResponse: bad DETAIL\n");	    return;	}	if ((t = d->resp_hdrs))	    httpHeaderParse(&htcpReply.hdr, t, t + strlen(t));	if ((t = d->entity_hdrs))	    httpHeaderParse(&htcpReply.hdr, t, t + strlen(t));	if ((t = d->cache_hdrs))	    httpHeaderParse(&htcpReply.hdr, t, t + strlen(t));    }    key = queried_keys[htcpReply.msg_id % N_QUERIED_KEYS];    debug(31, 3) ("htcpHandleTstResponse: key (%p) %s\n", key, storeKeyText(key));    neighborsHtcpReply(key, &htcpReply, from);    if (d)	htcpFreeDetail(d);}static voidhtcpHandleTstRequest(htcpDataHeader * dhdr, char *buf, int sz, struct sockaddr_in *from){    /* buf should be a SPECIFIER */    htcpSpecifier *s;    StoreEntry *e;    method_t m;    if (sz == 0) {	debug(31, 3) ("htcpHandleTst: nothing to do\n");	return;    }    if (dhdr->F1 == 0)	return;    s = htcpUnpackSpecifier(buf, sz);    if (NULL == s) {	debug(31, 3) ("htcpHandleTstRequest: htcpUnpackSpecifier failed\n");	return;    }    debug(31, 3) ("htcpHandleTstRequest: %s %s %s\n",	s->method,	s->uri,	s->version);    m = urlParseMethod(s->method);    debug(31, 3) ("htcpHandleTstRequest: %s\n", s->req_hdrs);    e = storeGetPublic(s->uri, m);    if (NULL == e) {	/* cache miss */	htcpTstReply(dhdr, NULL, NULL, from);#if WIP    } else if (!checkHeaders()) {	/* refresh/other miss */	htcpTstReply(dhdr, NULL, NULL, from);#endif    } else {	/* hit */	htcpTstReply(dhdr, e, s, from);    }    htcpFreeSpecifier(s);}static voidhtcpHandleMon(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from){    debug(31, 3) ("htcpHandleMon: Unimplemented\n");}static voidhtcpHandleSet(htcpDataHeader * hdr, char *buf, int sz, struct sockaddr_in *from){    debug(31, 3) ("htcpHandleSet: Unimplemented\n");}static voidhtcpHandleData(char *buf, int sz, struct sockaddr_in *from){    htcpDataHeader hdr;    if (sz < sizeof(htcpDataHeader)) {	debug(31, 0) ("htcpHandleData: msg size less than htcpDataHeader size\n");	return;    }    xmemcpy(&hdr, buf, sizeof(htcpDataHeader));    hdr.length = ntohs(hdr.length);    hdr.msg_id = ntohl(hdr.msg_id);    debug(31, 3) ("htcpHandleData: sz = %d\n", sz);    debug(31, 3) ("htcpHandleData: length = %d\n", (int) hdr.length);    if (hdr.opcode > HTCP_END) {	debug(31, 0) ("htcpHandleData: opcode %d out of range\n",	    (int) hdr.opcode);	return;    }    debug(31, 3) ("htcpHandleData: opcode = %d %s\n",	(int) hdr.opcode, htcpOpcodeStr[hdr.opcode]);    debug(31, 3) ("htcpHandleData: response = %d\n", (int) hdr.response);    debug(31, 3) ("htcpHandleData: F1 = %d\n", (int) hdr.F1);    debug(31, 3) ("htcpHandleData: RR = %d\n", (int) hdr.RR);    debug(31, 3) ("htcpHandleData: msg_id = %d\n", (int) hdr.msg_id);    if (sz < hdr.length) {	debug(31, 0) ("htcpHandle: sz < hdr.length\n");	return;    }    /*     * set sz = hdr.length so we ignore any AUTH fields following     * the DATA.     */    sz = (int) hdr.length;    buf += sizeof(htcpDataHeader);    sz -= sizeof(htcpDataHeader);    debug(31, 3) ("htcpHandleData: sz = %d\n", sz);    htcpHexdump("htcpHandleData", buf, sz);    switch (hdr.opcode) {    case HTCP_NOP:	htcpHandleNop(&hdr, buf, sz, from);	break;    case HTCP_TST:	htcpHandleTst(&hdr, buf, sz, from);	break;    case HTCP_MON:	htcpHandleMon(&hdr, buf, sz, from);	break;    case HTCP_SET:	htcpHandleSet(&hdr, buf, sz, from);	break;    default:	assert(0);	break;    }}static voidhtcpHandle(char *buf, int sz, struct sockaddr_in *from){    htcpHeader htcpHdr;    if (sz < sizeof(htcpHeader)) {	debug(31, 0) ("htcpHandle: msg size less than htcpHeader size\n");	return;    }    htcpHexdump("htcpHandle", buf, sz);    xmemcpy(&htcpHdr, buf, sizeof(htcpHeader));    htcpHdr.length = ntohs(htcpHdr.length);    debug(31, 3) ("htcpHandle: htcpHdr.length = %d\n", (int) htcpHdr.length);    debug(31, 3) ("htcpHandle: htcpHdr.major = %d\n", (int) htcpHdr.major);    debug(31, 3) ("htcpHandle: htcpHdr.minor = %d\n", (int) htcpHdr.minor);    if (sz != htcpHdr.length) {	debug(31, 0) ("htcpHandle: sz != htcpHdr.length\n");	return;    }    buf += sizeof(htcpHeader);    sz -= sizeof(htcpHeader);    htcpHandleData(buf, sz, from);}static voidhtcpRecv(int fd, void *data){    static char buf[8192];    int len;    static struct sockaddr_in from;    int flen = sizeof(struct sockaddr_in);    memset(&from, '\0', flen);    Counter.syscalls.sock.recvfroms++;    len = recvfrom(fd, buf, 8192, 0, (struct sockaddr *) &from, &flen);    debug(31, 3) ("htcpRecv: FD %d, %d bytes from %s:%d\n",	fd, len, inet_ntoa(from.sin_addr), ntohs(from.sin_port));    htcpHandle(buf, len, &from);    commSetSelect(fd, COMM_SELECT_READ, htcpRecv, NULL, 0);}/* * ====================================================================== * PUBLIC FUNCTIONS * ====================================================================== */voidhtcpInit(void){    enter_suid();    htcpInSocket = comm_open(SOCK_DGRAM,	0,	Config.Addrs.udp_incoming,	Config.Port.htcp,	COMM_NONBLOCKING,	"HTCP Socket");    leave_suid();    if (htcpInSocket < 0)	fatal("Cannot open HTCP Socket");    commSetSelect(htcpInSocket, COMM_SELECT_READ, htcpRecv, NULL, 0);    debug(31, 1) ("Accepting HTCP messages on port %d, FD %d.\n",	(int) Config.Port.htcp, htcpInSocket);    if (Config.Addrs.udp_outgoing.s_addr != no_addr.s_addr) {	enter_suid();	htcpOutSocket = comm_open(SOCK_DGRAM,	    0,	    Config.Addrs.udp_outgoing,	    Config.Port.htcp,	    COMM_NONBLOCKING,	    "Outgoing HTCP Socket");	leave_suid();	if (htcpOutSocket < 0)	    fatal("Cannot open Outgoing HTCP Socket");	commSetSelect(htcpOutSocket, COMM_SELECT_READ, htcpRecv, NULL, 0);	debug(31, 1) ("Outgoing HTCP messages on port %d, FD %d.\n",	    (int) Config.Port.htcp, htcpOutSocket);	fd_note(htcpInSocket, "Incoming HTCP socket");    } else {	htcpOutSocket = htcpInSocket;    }}voidhtcpQuery(StoreEntry * e, request_t * req, peer * p){    cache_key *save_key;    char *pkt;    ssize_t pktlen;    char vbuf[32];    htcpStuff stuff;    HttpHeader hdr;    Packer pa;    MemBuf mb;    http_state_flags flags;    memset(&flags, '\0', sizeof(flags));    snprintf(vbuf, sizeof(vbuf), "%3.1f", req->http_ver);    stuff.op = HTCP_TST;    stuff.rr = RR_REQUEST;    stuff.f1 = 1;    stuff.response = 0;    stuff.msg_id = ++msg_id_counter;    stuff.S.method = (char *) RequestMethodStr[req->method];    stuff.S.uri = (char *) storeUrl(e);    stuff.S.version = vbuf;    httpBuildRequestHeader(req, req, e, &hdr, -1, flags);    memBufDefInit(&mb);    packerToMemInit(&pa, &mb);    httpHeaderPackInto(&hdr, &pa);    httpHeaderClean(&hdr);    packerClean(&pa);    stuff.S.req_hdrs = mb.buf;    pkt = htcpBuildPacket(&stuff, &pktlen);    if (pkt == NULL) {	debug(31, 0) ("htcpQuery: htcpBuildPacket() failed\n");	return;    }    htcpSend(pkt, (int) pktlen, &p->in_addr);    save_key = queried_keys[stuff.msg_id % N_QUERIED_KEYS];    storeKeyCopy(save_key, e->key);    debug(31, 3) ("htcpQuery: key (%p) %s\n", save_key, storeKeyText(save_key));    xfree(pkt);}/*   * htcpSocketShutdown only closes the 'in' socket if it is * different than the 'out' socket. */voidhtcpSocketShutdown(void){    if (htcpInSocket < 0)	return;    if (htcpInSocket != htcpOutSocket) {	debug(12, 1) ("FD %d Closing HTCP socket\n", htcpInSocket);	comm_close(htcpInSocket);    }    /*           * Here we set 'htcpInSocket' to -1 even though the HTCP 'in'     * and 'out' sockets might be just one FD.  This prevents this     * function from executing repeatedly.  When we are really ready to     * exit or restart, main will comm_close the 'out' descriptor.     */    htcpInSocket = -1;    /*           * Normally we only write to the outgoing HTCP socket, but     * we also have a read handler there to catch messages sent     * to that specific interface.  During shutdown, we must     * disable reading on the outgoing socket.     */    assert(htcpOutSocket > -1);    commSetSelect(htcpOutSocket, COMM_SELECT_READ, NULL, NULL, 0);}voidhtcpSocketClose(void){    htcpSocketShutdown();    if (htcpOutSocket > -1) {	debug(12, 1) ("FD %d Closing HTCP socket\n", htcpOutSocket);	comm_close(htcpOutSocket);    }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -