]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/ident.cc
3 * $Id: ident.cc,v 1.56 2001/01/12 00:37:18 wessels Exp $
5 * DEBUG: section 30 Ident (RFC 931)
6 * AUTHOR: Duane Wessels
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
40 #define IDENT_PORT 113
41 #define IDENT_KEY_SZ 50
43 typedef struct _IdentClient
{
46 struct _IdentClient
*next
;
49 typedef struct _IdentStateData
{
50 hash_link hash
; /* must be first */
51 int fd
; /* IDENT fd */
52 struct sockaddr_in me
;
53 struct sockaddr_in my_peer
;
57 static PF identReadReply
;
59 static PF identTimeout
;
60 static CNCB identConnectDone
;
61 static hash_table
*ident_hash
= NULL
;
62 static void identClientAdd(IdentStateData
*, IDCB
*, void *);
64 /**** PRIVATE FUNCTIONS ****/
67 identCallback(IdentStateData
* state
, char *result
)
70 if (result
&& *result
== '\0')
72 while ((client
= state
->clients
)) {
73 state
->clients
= client
->next
;
74 if (cbdataValid(client
->callback_data
))
75 client
->callback(result
, client
->callback_data
);
76 cbdataUnlock(client
->callback_data
);
82 identClose(int fdnotused
, void *data
)
84 IdentStateData
*state
= data
;
85 identCallback(state
, NULL
);
86 comm_close(state
->fd
);
87 hash_remove_link(ident_hash
, (hash_link
*) state
);
92 identTimeout(int fd
, void *data
)
94 IdentStateData
*state
= data
;
95 debug(30, 3) ("identTimeout: FD %d, %s\n", fd
,
96 inet_ntoa(state
->my_peer
.sin_addr
));
101 identConnectDone(int fd
, int status
, void *data
)
103 IdentStateData
*state
= data
;
106 if (status
!= COMM_OK
) {
107 /* Failed to connect */
112 * see if our clients still care
114 for (c
= state
->clients
; c
; c
= c
->next
) {
115 if (cbdataValid(c
->callback_data
))
119 /* no clients care */
124 memBufPrintf(&mb
, "%d, %d\r\n",
125 ntohs(state
->my_peer
.sin_port
),
126 ntohs(state
->me
.sin_port
));
127 comm_write_mbuf(fd
, mb
, NULL
, state
);
128 commSetSelect(fd
, COMM_SELECT_READ
, identReadReply
, state
, 0);
129 commSetTimeout(fd
, Config
.Timeout
.ident
, identTimeout
, state
);
133 identReadReply(int fd
, void *data
)
135 IdentStateData
*state
= data
;
136 LOCAL_ARRAY(char, buf
, BUFSIZ
);
141 statCounter
.syscalls
.sock
.reads
++;
142 len
= read(fd
, buf
, BUFSIZ
- 1);
143 fd_bytes(fd
, len
, FD_READ
);
149 * XXX This isn't really very tolerant. It should read until EOL
150 * or EOF and then decode the answer... If the reply is fragmented
151 * then this will fail
154 if ((t
= strchr(buf
, '\r')))
156 if ((t
= strchr(buf
, '\n')))
158 debug(30, 5) ("identReadReply: FD %d: Read '%s'\n", fd
, buf
);
159 if (strstr(buf
, "USERID")) {
160 if ((ident
= strrchr(buf
, ':'))) {
161 while (xisspace(*++ident
));
162 identCallback(state
, ident
);
170 identClientAdd(IdentStateData
* state
, IDCB
* callback
, void *callback_data
)
172 IdentClient
*c
= xcalloc(1, sizeof(*c
));
174 c
->callback
= callback
;
175 c
->callback_data
= callback_data
;
176 cbdataLock(callback_data
);
177 for (C
= &state
->clients
; *C
; C
= &(*C
)->next
);
181 CBDATA_TYPE(IdentStateData
);
183 /**** PUBLIC FUNCTIONS ****/
186 * start a TCP connection to the peer host on port 113
189 identStart(struct sockaddr_in
*me
, struct sockaddr_in
*my_peer
, IDCB
* callback
, void *data
)
191 IdentStateData
*state
;
193 char key1
[IDENT_KEY_SZ
];
194 char key2
[IDENT_KEY_SZ
];
195 char key
[IDENT_KEY_SZ
];
196 snprintf(key1
, IDENT_KEY_SZ
, "%s:%d",
197 inet_ntoa(me
->sin_addr
),
198 ntohs(me
->sin_port
));
199 snprintf(key2
, IDENT_KEY_SZ
, "%s:%d",
200 inet_ntoa(my_peer
->sin_addr
),
201 ntohs(my_peer
->sin_port
));
202 snprintf(key
, IDENT_KEY_SZ
, "%s,%s", key1
, key2
);
203 if ((state
= hash_lookup(ident_hash
, key
)) != NULL
) {
204 identClientAdd(state
, callback
, data
);
207 fd
= comm_open(SOCK_STREAM
,
213 if (fd
== COMM_ERROR
) {
214 /* Failed to get a local socket */
215 callback(NULL
, data
);
218 CBDATA_INIT_TYPE(IdentStateData
);
219 state
= CBDATA_ALLOC(IdentStateData
, NULL
);
220 state
->hash
.key
= xstrdup(key
);
223 state
->my_peer
= *my_peer
;
224 identClientAdd(state
, callback
, data
);
225 hash_join(ident_hash
, &state
->hash
);
226 comm_add_close_handler(fd
,
229 commSetTimeout(fd
, Config
.Timeout
.ident
, identTimeout
, state
);
231 inet_ntoa(state
->my_peer
.sin_addr
),
240 ident_hash
= hash_create((HASHCMP
*) strcmp
,
241 hashPrime(Squid_MaxFD
/ 8),