ViewVC Help
View File | Revision Log | Show Annotations | View Changeset | Root Listing
root/svn/ircd-hybrid/trunk/src/s_bsd_devpoll.c
Revision: 2725
Committed: Sun Dec 29 13:01:00 2013 UTC (11 years, 8 months ago) by michael
Content type: text/x-csrc
File size: 4586 byte(s)
Log Message:
- Fixed bug where ircd didn't timeout SSL connections that haven't
  finished the SSL handshake. Reported by Adam.

File Contents

# Content
1 /*
2 * ircd-hybrid: an advanced Internet Relay Chat Daemon(ircd).
3 * s_bsd_devpoll.c: /dev/poll compatible network routines.
4 *
5 * Originally by Adrian Chadd <adrian@creative.net.au>
6 * Copyright (C) 2002 Hybrid Development Team
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21 * USA
22 *
23 * $Id$
24 */
25
26 #include "stdinc.h"
27 #if USE_IOPOLL_MECHANISM == __IOPOLL_MECHANISM_DEVPOLL
28 #include <sys/ioctl.h>
29 /* HPUX uses devpoll.h and not sys/devpoll.h */
30 #ifdef HAVE_DEVPOLL_H
31 # include <devpoll.h>
32 #else
33 # ifdef HAVE_SYS_DEVPOLL_H
34 # include <sys/devpoll.h>
35 # else
36 # error "No devpoll.h found! Try ./configuring and letting the script choose for you."
37 # endif
38 #endif
39 #include "fdlist.h"
40 #include "ircd.h"
41 #include "s_bsd.h"
42 #include "log.h"
43
44 static fde_t dpfd;
45
46 /*
47 * init_netio
48 *
49 * This is a needed exported function which will be called to initialise
50 * the network loop code.
51 */
52 void
53 init_netio(void)
54 {
55 int fd;
56
57 if ((fd = open("/dev/poll", O_RDWR)) < 0)
58 {
59 ilog(LOG_TYPE_IRCD, "init_netio: Couldn't open /dev/poll - %d: %s",
60 errno, strerror(errno));
61 exit(115); /* Whee! */
62 }
63
64 fd_open(&dpfd, fd, 0, "/dev/poll file descriptor");
65 }
66
67 /*
68 * Write an update to the devpoll filter.
69 * See, we end up having to do a seperate (?) remove before we do an
70 * add of a new polltype, so we have to have this function seperate from
71 * the others.
72 */
73 static void
74 devpoll_write_update(int fd, int events)
75 {
76 struct pollfd pfd;
77
78 /* Build the pollfd entry */
79 pfd.revents = 0;
80 pfd.fd = fd;
81 pfd.events = events;
82
83 /* Write the thing to our poll fd */
84 if (write(dpfd.fd, &pfd, sizeof(pfd)) != sizeof(pfd))
85 ilog(LOG_TYPE_IRCD, "devpoll_write_update: dpfd write failed %d: %s",
86 errno, strerror(errno));
87 }
88
89 /*
90 * comm_setselect
91 *
92 * This is a needed exported function which will be called to register
93 * and deregister interest in a pending IO state for a given FD.
94 */
95 void
96 comm_setselect(fde_t *F, unsigned int type, PF *handler,
97 void *client_data, time_t timeout)
98 {
99 int new_events;
100
101 if ((type & COMM_SELECT_READ))
102 {
103 F->read_handler = handler;
104 F->read_data = client_data;
105 }
106
107 if ((type & COMM_SELECT_WRITE))
108 {
109 F->write_handler = handler;
110 F->write_data = client_data;
111 }
112
113 new_events = (F->read_handler ? POLLIN : 0) |
114 (F->write_handler ? POLLOUT : 0);
115
116 if (timeout != 0)
117 {
118 F->timeout = CurrentTime + (timeout / 1000);
119 F->timeout_handler = handler;
120 F->timeout_data = client_data;
121 }
122
123 if (new_events != F->evcache)
124 {
125 devpoll_write_update(F->fd, POLLREMOVE);
126 if ((F->evcache = new_events))
127 devpoll_write_update(F->fd, new_events);
128 }
129 }
130
131 /*
132 * comm_select
133 *
134 * Called to do the new-style IO, courtesy of squid (like most of this
135 * new IO code). This routine handles the stuff we've hidden in
136 * comm_setselect and fd_table[] and calls callbacks for IO ready
137 * events.
138 */
139 void
140 comm_select(void)
141 {
142 int num, i;
143 struct pollfd pollfds[128];
144 struct dvpoll dopoll;
145 PF *hdl;
146 fde_t *F;
147
148 dopoll.dp_timeout = SELECT_DELAY;
149 dopoll.dp_nfds = 128;
150 dopoll.dp_fds = &pollfds[0];
151 num = ioctl(dpfd.fd, DP_POLL, &dopoll);
152
153 set_time();
154
155 if (num < 0)
156 {
157 #ifdef HAVE_USLEEP
158 usleep(50000); /* avoid 99% CPU in comm_select */
159 #endif
160 return;
161 }
162
163 for (i = 0; i < num; i++)
164 {
165 F = lookup_fd(dopoll.dp_fds[i].fd);
166 if (F == NULL || !F->flags.open)
167 continue;
168
169 if ((dopoll.dp_fds[i].revents & POLLIN))
170 {
171 if ((hdl = F->read_handler) != NULL)
172 {
173 F->read_handler = NULL;
174 hdl(F, F->read_data);
175 if (!F->flags.open)
176 continue;
177 }
178 }
179
180 if ((dopoll.dp_fds[i].revents & POLLOUT))
181 {
182 if ((hdl = F->write_handler) != NULL)
183 {
184 F->write_handler = NULL;
185 hdl(F, F->write_data);
186 if (!F->flags.open)
187 continue;
188 }
189 }
190
191 comm_setselect(F, 0, NULL, NULL, 0);
192 }
193 }
194 #endif

Properties

Name Value
svn:eol-style native
svn:keywords Id Revision