ident.c
来自「-」· C语言 代码 · 共 245 行
C
245 行
/* * $Id: ident.c,v 1.49.2.1 1999/02/12 19:38:30 wessels Exp $ * * DEBUG: section 30 Ident (RFC 931) * AUTHOR: Duane Wessels * * 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"#if USE_IDENT#define IDENT_PORT 113#define IDENT_KEY_SZ 50typedef struct _IdentClient { IDCB *callback; void *callback_data; struct _IdentClient *next;} IdentClient;typedef struct _IdentStateData { char *key; struct _IdentStateData *next; int fd; /* IDENT fd */ struct sockaddr_in me; struct sockaddr_in peer; IdentClient *clients;} IdentStateData;static PF identReadReply;static PF identClose;static PF identTimeout;static CNCB identConnectDone;static hash_table *ident_hash = NULL;static void identClientAdd(IdentStateData *, IDCB *, void *);/**** PRIVATE FUNCTIONS ****/static voididentCallback(IdentStateData * state, char *result){ IdentClient *client; if (result && *result == '\0') result = NULL; while ((client = state->clients)) { state->clients = client->next; if (cbdataValid(client->callback_data)) client->callback(result, client->callback_data); cbdataUnlock(client->callback_data); xfree(client); }}static voididentClose(int fdnotused, void *data){ IdentStateData *state = data; identCallback(state, NULL); comm_close(state->fd); hash_remove_link(ident_hash, (hash_link *) state); cbdataFree(state);}static voididentTimeout(int fd, void *data){ IdentStateData *state = data; debug(30, 3) ("identTimeout: FD %d, %s\n", fd, inet_ntoa(state->peer.sin_addr)); comm_close(fd);}static voididentConnectDone(int fd, int status, void *data){ IdentStateData *state = data; IdentClient *c; MemBuf mb; if (status != COMM_OK) { /* Failed to connect */ comm_close(fd); return; } /* * see if our clients still care */ for (c = state->clients; c; c = c->next) { if (cbdataValid(c->callback_data)) break; } if (c == NULL) { /* no clients care */ comm_close(fd); return; } memBufDefInit(&mb); memBufPrintf(&mb, "%d, %d\r\n", ntohs(state->peer.sin_port), ntohs(state->me.sin_port)); comm_write_mbuf(fd, mb, NULL, state); commSetSelect(fd, COMM_SELECT_READ, identReadReply, state, 0); commSetTimeout(fd, Config.Timeout.ident, identTimeout, state);}static voididentReadReply(int fd, void *data){ IdentStateData *state = data; LOCAL_ARRAY(char, buf, BUFSIZ); char *ident = NULL; char *t = NULL; int len = -1; buf[0] = '\0'; Counter.syscalls.sock.reads++; len = read(fd, buf, BUFSIZ - 1); fd_bytes(fd, len, FD_READ); if (len <= 0) { comm_close(fd); return; } /* * XXX This isn't really very tolerant. It should read until EOL * or EOF and then decode the answer... If the reply is fragmented * then this will fail */ buf[len] = '\0'; if ((t = strchr(buf, '\r'))) *t = '\0'; if ((t = strchr(buf, '\n'))) *t = '\0'; debug(30, 5) ("identReadReply: FD %d: Read '%s'\n", fd, buf); if (strstr(buf, "USERID")) { if ((ident = strrchr(buf, ':'))) { while (xisspace(*++ident)); identCallback(state, ident); } } comm_close(fd);}static voididentClientAdd(IdentStateData * state, IDCB * callback, void *callback_data){ IdentClient *c = xcalloc(1, sizeof(*c)); IdentClient **C; c->callback = callback; c->callback_data = callback_data; cbdataLock(callback_data); for (C = &state->clients; *C; C = &(*C)->next); *C = c;}/**** PUBLIC FUNCTIONS ****//* * start a TCP connection to the peer host on port 113 */voididentStart(struct sockaddr_in *me, struct sockaddr_in *peer, IDCB * callback, void *data){ IdentStateData *state; int fd; char key1[IDENT_KEY_SZ]; char key2[IDENT_KEY_SZ]; char key[IDENT_KEY_SZ]; snprintf(key1, IDENT_KEY_SZ, "%s:%d", inet_ntoa(me->sin_addr), ntohs(me->sin_port)); snprintf(key2, IDENT_KEY_SZ, "%s:%d", inet_ntoa(peer->sin_addr), ntohs(peer->sin_port)); snprintf(key, IDENT_KEY_SZ, "%s,%s", key1, key2); if ((state = hash_lookup(ident_hash, key)) != NULL) { identClientAdd(state, callback, data); return; } fd = comm_open(SOCK_STREAM, 0, me->sin_addr, 0, COMM_NONBLOCKING, "ident"); if (fd == COMM_ERROR) { /* Failed to get a local socket */ callback(NULL, data); return; } state = xcalloc(1, sizeof(IdentStateData)); cbdataAdd(state, cbdataXfree, 0); state->key = xstrdup(key); state->fd = fd; state->me = *me; state->peer = *peer; identClientAdd(state, callback, data); hash_join(ident_hash, (hash_link *) state); comm_add_close_handler(fd, identClose, state); commSetTimeout(fd, Config.Timeout.ident, identTimeout, state); commConnectStart(fd, inet_ntoa(state->peer.sin_addr), IDENT_PORT, identConnectDone, state);}voididentInit(void){ ident_hash = hash_create((HASHCMP *) strcmp, hashPrime(Squid_MaxFD / 8), hash4);}#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?