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

📄 htcp.c

📁 -
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * $Id: htcp.c,v 1.26 1998/10/08 20:10:21 wessels Exp $ * * DEBUG: section 31    Hypertext Caching Protocol * AUTHOR: Duane Wesssels * * SQUID Internet Object Cache  http://squid.nlanr.net/Squid/ * ---------------------------------------------------------- * *  Squid is the result of efforts by numerous individuals from the *  Internet community.  Development is led by Duane Wessels of the *  National Laboratory for Applied Network Research and funded by the *  National Science Foundation.  Squid is Copyrighted (C) 1998 by *  Duane Wessels and the University of California San Diego.  Please *  see the COPYRIGHT file for full details.  Squid incorporates *  software developed and/or copyrighted by other sources.  Please see *  the CREDITS file for full details. * *  This program is free software; you can redistribute it and/or modify *  it under the terms of the GNU General Public License as published by *  the Free Software Foundation; either version 2 of the License, or *  (at your option) any later version. *   *  This program is distributed in the hope that it will be useful, *  but WITHOUT ANY WARRANTY; without even the implied warranty of *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *  GNU General Public License for more details. *   *  You should have received a copy of the GNU General Public License *  along with this program; if not, write to the Free Software *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA. * */#include "squid.h"typedef struct _Countstr Countstr;typedef struct _htcpHeader htcpHeader;typedef struct _htcpDataHeader htcpDataHeader;typedef struct _htcpAuthHeader htcpAuthHeader;typedef struct _htcpStuff htcpStuff;typedef struct _htcpSpecifier htcpSpecifier;typedef struct _htcpDetail htcpDetail;struct _Countstr {    u_short length;    char *text;};struct _htcpHeader {    u_short length;    u_char major;    u_char minor;};struct _htcpDataHeader {    u_short length;#if !WORDS_BIGENDIAN    u_char opcode:4;    u_char response:4;#else    u_char response:4;    u_char opcode:4;#endif#if !WORDS_BIGENDIAN    u_char reserved:6;    u_char F1:1;    u_char RR:1;#else    u_char RR:1;    u_char F1:1;    u_char reserved:6;#endif    u_num32 msg_id;};    /* RR == 0 --> F1 = RESPONSE DESIRED FLAG */    /* RR == 1 --> F1 = MESSAGE OVERALL FLAG */    /* RR == 0 --> REQUEST */    /* RR == 1 --> RESPONSE */struct _htcpAuthHeader {    u_short length;    time_t sig_time;    time_t sig_expire;    Countstr key_name;    Countstr signature;};struct _htcpSpecifier {    char *method;    char *uri;    char *version;    char *req_hdrs;};struct _htcpDetail {    char *resp_hdrs;    char *entity_hdrs;    char *cache_hdrs;};struct _htcpStuff {    int op;    int rr;    int f1;    int response;    u_num32 msg_id;    htcpSpecifier S;    htcpDetail D;};enum {    HTCP_NOP,    HTCP_TST,    HTCP_MON,    HTCP_SET,    HTCP_CLR,    HTCP_END};static const char *const htcpOpcodeStr[] ={    "HTCP_NOP",    "HTCP_TST",    "HTCP_MON",    "HTCP_SET",    "HTCP_CLR",    "HTCP_END"};/* * values for htcpDataHeader->response */enum {    AUTH_REQUIRED,    AUTH_FAILURE,    OPCODE_UNIMPLEMENTED,    MAJOR_VERSION_UNSUPPORTED,    MINOR_VERSION_UNSUPPORTED,    INVALID_OPCODE};/* * values for htcpDataHeader->RR */enum {    RR_REQUEST,    RR_RESPONSE};static u_num32 msg_id_counter = 0;static int htcpInSocket = -1;static int htcpOutSocket = -1;#define N_QUERIED_KEYS 256static cache_key queried_keys[N_QUERIED_KEYS][MD5_DIGEST_CHARS];static char *htcpBuildPacket(htcpStuff * stuff, ssize_t * len);static htcpSpecifier *htcpUnpackSpecifier(char *buf, int sz);static htcpDetail *htcpUnpackDetail(char *buf, int sz);static int htcpUnpackCountstr(char *buf, int sz, char **str);static ssize_t htcpBuildAuth(char *buf, size_t buflen);static ssize_t htcpBuildCountstr(char *buf, size_t buflen, const char *s);static ssize_t htcpBuildData(char *buf, size_t buflen, htcpStuff * stuff);static ssize_t htcpBuildDetail(char *buf, size_t buflen, htcpStuff * stuff);static ssize_t htcpBuildOpData(char *buf, size_t buflen, htcpStuff * stuff);static ssize_t htcpBuildSpecifier(char *buf, size_t buflen, htcpStuff * stuff);static ssize_t htcpBuildTstOpData(char *buf, size_t buflen, htcpStuff * stuff);static void htcpFreeSpecifier(htcpSpecifier * s);static void htcpFreeDetail(htcpDetail * s);static void htcpHandle(char *buf, int sz, struct sockaddr_in *from);static void htcpHandleData(char *buf, int sz, struct sockaddr_in *from);static void htcpHandleMon(htcpDataHeader *, char *buf, int sz, struct sockaddr_in *from);static void htcpHandleNop(htcpDataHeader *, char *buf, int sz, struct sockaddr_in *from);static void htcpHandleSet(htcpDataHeader *, char *buf, int sz, struct sockaddr_in *from);static void htcpHandleTst(htcpDataHeader *, char *buf, int sz, struct sockaddr_in *from);static void htcpRecv(int fd, void *data);static void htcpSend(const char *buf, int len, struct sockaddr_in *to);static void htcpTstReply(htcpDataHeader *, StoreEntry *, htcpSpecifier *, struct sockaddr_in *);static void htcpHandleTstRequest(htcpDataHeader *, char *buf, int sz, struct sockaddr_in *from);static void htcpHandleTstResponse(htcpDataHeader *, char *, int, struct sockaddr_in *);static voidhtcpHexdump(const char *tag, const char *s, int sz){#if USE_HEXDUMP    int i;    int k;    char hex[80];    debug(31, 3) ("htcpHexdump %s\n", tag);    memset(hex, '\0', 80);    for (i = 0; i < sz; i++) {	k = i % 16;	snprintf(&hex[k * 3], 4, " %02x", (int) *(s + i));	if (k < 15 && i < (sz - 1))	    continue;	debug(31, 3) ("\t%s\n", hex);	memset(hex, '\0', 80);    }#endif}/* * STUFF FOR SENDING HTCP MESSAGES */static ssize_thtcpBuildAuth(char *buf, size_t buflen){    htcpAuthHeader auth;    size_t copy_sz = 0;    assert(2 == sizeof(u_short));    auth.length = htons(2);    copy_sz += 2;    assert(buflen >= copy_sz);    xmemcpy(buf, &auth, copy_sz);    return copy_sz;}static ssize_thtcpBuildCountstr(char *buf, size_t buflen, const char *s){    u_short length;    size_t len;    off_t off = 0;    if (buflen - off < 2)	return -1;    if (s)	len = strlen(s);    else	len = 0;    debug(31, 3) ("htcpBuildCountstr: LENGTH = %d\n", len);    debug(31, 3) ("htcpBuildCountstr: TEXT = {%s}\n", s ? s : "<NULL>");    length = htons((u_short) len);    xmemcpy(buf + off, &length, 2);    off += 2;    if (buflen - off < len)	return -1;    if (len)	xmemcpy(buf + off, s, len);    off += len;    return off;}static ssize_thtcpBuildSpecifier(char *buf, size_t buflen, htcpStuff * stuff){    ssize_t off = 0;    ssize_t s;    s = htcpBuildCountstr(buf + off, buflen - off, stuff->S.method);    if (s < 0)	return s;    off += s;    s = htcpBuildCountstr(buf + off, buflen - off, stuff->S.uri);    if (s < 0)	return s;    off += s;    s = htcpBuildCountstr(buf + off, buflen - off, stuff->S.version);    if (s < 0)	return s;    off += s;    s = htcpBuildCountstr(buf + off, buflen - off, stuff->S.req_hdrs);    if (s < 0)	return s;    off += s;    debug(31, 3) ("htcpBuildSpecifier: size %d\n", (int) off);    return off;}static ssize_thtcpBuildDetail(char *buf, size_t buflen, htcpStuff * stuff){    ssize_t off = 0;    ssize_t s;    s = htcpBuildCountstr(buf + off, buflen - off, stuff->D.resp_hdrs);    if (s < 0)	return s;    off += s;    s = htcpBuildCountstr(buf + off, buflen - off, stuff->D.entity_hdrs);    if (s < 0)	return s;    off += s;    s = htcpBuildCountstr(buf + off, buflen - off, stuff->D.cache_hdrs);    if (s < 0)	return s;    off += s;    return off;}static ssize_thtcpBuildTstOpData(char *buf, size_t buflen, htcpStuff * stuff){    switch (stuff->rr) {    case RR_REQUEST:	debug(31, 3) ("htcpBuildTstOpData: RR_REQUEST\n");	return htcpBuildSpecifier(buf, buflen, stuff);    case RR_RESPONSE:	debug(31, 3) ("htcpBuildTstOpData: RR_RESPONSE\n");	debug(31, 3) ("htcpBuildTstOpData: F1 = %d\n", stuff->f1);	if (stuff->f1)		/* cache miss */	    return 0;	else			/* cache hit */	    return htcpBuildDetail(buf, buflen, stuff);    default:	fatal_dump("htcpBuildTstOpData: bad RR value");    }    return 0;}static ssize_thtcpBuildOpData(char *buf, size_t buflen, htcpStuff * stuff){    ssize_t off = 0;    debug(31, 3) ("htcpBuildOpData: opcode %s\n",	htcpOpcodeStr[stuff->op]);    switch (stuff->op) {    case HTCP_TST:	off = htcpBuildTstOpData(buf + off, buflen, stuff);	break;    default:	assert(0);	break;    }    return off;}static ssize_thtcpBuildData(char *buf, size_t buflen, htcpStuff * stuff){    ssize_t off = 0;    ssize_t op_data_sz;    size_t hdr_sz = sizeof(htcpDataHeader);    htcpDataHeader hdr;    if (buflen < hdr_sz)	return -1;    off += hdr_sz;		/* skip! */    op_data_sz = htcpBuildOpData(buf + off, buflen - off, stuff);    if (op_data_sz < 0)	return op_data_sz;    off += op_data_sz;    debug(31, 3) ("htcpBuildData: hdr.length = %d\n", (int) off);    hdr.length = (u_short) off;    hdr.opcode = stuff->op;    hdr.response = stuff->response;    hdr.RR = stuff->rr;    hdr.F1 = stuff->f1;    hdr.msg_id = stuff->msg_id;    /* convert multi-byte fields */    hdr.length = htons(hdr.length);    hdr.msg_id = htonl(hdr.msg_id);    xmemcpy(buf, &hdr, hdr_sz);    debug(31, 3) ("htcpBuildData: size %d\n", (int) off);    return off;}static char *htcpBuildPacket(htcpStuff * stuff, ssize_t * len){    size_t buflen = 8192;    size_t s;    ssize_t off = 0;    size_t hdr_sz = sizeof(htcpHeader);    htcpHeader hdr;    char *buf = xcalloc(buflen, 1);    /* skip the header -- we don't know the overall length */    if (buflen < hdr_sz)	return NULL;    off += hdr_sz;    s = htcpBuildData(buf + off, buflen - off, stuff);    if (s < 0)	return NULL;    off += s;    s = htcpBuildAuth(buf + off, buflen - off);    if (s < 0)	return NULL;    off += s;    hdr.length = htons((u_short) off);    hdr.major = 0;    hdr.minor = 0;    xmemcpy(buf, &hdr, hdr_sz);    *len = off;    debug(31, 3) ("htcpBuildPacket: size %d\n", (int) off);    return buf;}static voidhtcpSend(const char *buf, int len, struct sockaddr_in *to){    int x;    debug(31, 3) ("htcpSend: %s/%d\n",	inet_ntoa(to->sin_addr), (int) ntohs(to->sin_port));    htcpHexdump("htcpSend", buf, len);    x = comm_udp_sendto(htcpOutSocket,	to,	sizeof(struct sockaddr_in),	buf,	len);    if (x < 0)	debug(31, 0) ("htcpSend: FD %d sendto: %s\n", htcpOutSocket, xstrerror());}/* * STUFF FOR RECEIVING HTCP MESSAGES */static voidhtcpFreeSpecifier(htcpSpecifier * s){    safe_free(s->method);    safe_free(s->uri);    safe_free(s->version);    safe_free(s->req_hdrs);    xfree(s);}static voidhtcpFreeDetail(htcpDetail * d){    safe_free(d->resp_hdrs);    safe_free(d->entity_hdrs);    safe_free(d->cache_hdrs);    xfree(d);}static inthtcpUnpackCountstr(char *buf, int sz, char **str){    u_short l;    debug(31, 3) ("htcpUnpackCountstr: sz = %d\n", sz);    if (sz < 2) {	debug(31, 3) ("htcpUnpackCountstr: sz < 2\n");	return -1;    }    htcpHexdump("htcpUnpackCountstr", buf, sz);    xmemcpy(&l, buf, 2);    l = ntohs(l);    buf += 2;    sz -= 2;    debug(31, 3) ("htcpUnpackCountstr: LENGTH = %d\n", (int) l);    if (sz < l) {	debug(31, 3) ("htcpUnpackCountstr: sz(%d) < l(%d)\n", sz, l);	return -1;    }    if (str) {	*str = xmalloc(l + 1);	xstrncpy(*str, buf, l + 1);	debug(31, 3) ("htcpUnpackCountstr: TEXT = {%s}\n", *str);    }    return (int) l + 2;}static htcpSpecifier *htcpUnpackSpecifier(char *buf, int sz){    htcpSpecifier *s = xcalloc(1, sizeof(htcpSpecifier));    int o;    debug(31, 3) ("htcpUnpackSpecifier: %d bytes\n", (int) sz);    o = htcpUnpackCountstr(buf, sz, &s->method);    if (o < 0) {	debug(31, 1) ("htcpUnpackSpecifier: failed to unpack METHOD\n");

⌨️ 快捷键说明

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