… | |
… | |
3 | * Rights to this code are documented in doc/pod/license.pod. |
3 | * Rights to this code are documented in doc/pod/license.pod. |
4 | * |
4 | * |
5 | * Handling of streams and packet queues. |
5 | * Handling of streams and packet queues. |
6 | */ |
6 | */ |
7 | |
7 | |
8 | static char const rcsid[] = "$Id: datastream.C,v 1.4 2007/08/28 17:08:12 pippijn Exp $"; |
8 | static char const rcsid[] = "$Id: datastream.C,v 1.5 2007/08/30 19:56:24 pippijn Exp $"; |
9 | |
9 | |
10 | #include "atheme.h" |
10 | #include "atheme.h" |
11 | #include "datastream.h" |
11 | #include "datastream.h" |
12 | #include "connection.h" |
12 | #include "connection.h" |
13 | |
13 | |
… | |
… | |
16 | { |
16 | { |
17 | packetqueue *sq; |
17 | packetqueue *sq; |
18 | int l; |
18 | int l; |
19 | int pos = 0; |
19 | int pos = 0; |
20 | |
20 | |
21 | if (cptr->flags & (CF_DEAD | CF_SEND_EOF)) |
21 | if (cptr->flags & (connection_t::CF_DEAD | connection_t::CF_SEND_EOF)) |
22 | { |
22 | { |
23 | slog (LG_DEBUG, "sendq_add(): attempted to send to fd %d which is already dead", cptr->fd); |
23 | slog (LG_DEBUG, "sendq_add(): attempted to send to fd %d which is already dead", cptr->fd); |
24 | return; |
24 | return; |
25 | } |
25 | } |
26 | |
26 | |
… | |
… | |
51 | } |
51 | } |
52 | |
52 | |
53 | void |
53 | void |
54 | sendq_add_eof (connection_t *cptr) |
54 | sendq_add_eof (connection_t *cptr) |
55 | { |
55 | { |
56 | if (cptr->flags & (CF_DEAD | CF_SEND_EOF)) |
56 | if (cptr->flags & (connection_t::CF_DEAD | connection_t::CF_SEND_EOF)) |
57 | { |
57 | { |
58 | slog (LG_DEBUG, "sendq_add(): attempted to send to fd %d which is already dead", cptr->fd); |
58 | slog (LG_DEBUG, "sendq_add(): attempted to send to fd %d which is already dead", cptr->fd); |
59 | return; |
59 | return; |
60 | } |
60 | } |
61 | cptr->flags |= CF_SEND_EOF; |
61 | cptr->flags |= connection_t::CF_SEND_EOF; |
62 | } |
62 | } |
63 | |
63 | |
64 | void |
64 | void |
65 | sendq_flush (connection_t *cptr) |
65 | sendq_flush (connection_t *cptr) |
66 | { |
66 | { |
… | |
… | |
77 | if ((l = write (cptr->fd, sq->buf + sq->firstused, sq->firstfree - sq->firstused)) == -1) |
77 | if ((l = write (cptr->fd, sq->buf + sq->firstused, sq->firstfree - sq->firstused)) == -1) |
78 | { |
78 | { |
79 | if (errno != EAGAIN) |
79 | if (errno != EAGAIN) |
80 | { |
80 | { |
81 | slog (LG_DEBUG, "sendq_flush(): write error %d (%s) on connection %s[%d]", errno, strerror (errno), cptr->name, cptr->fd); |
81 | slog (LG_DEBUG, "sendq_flush(): write error %d (%s) on connection %s[%d]", errno, strerror (errno), cptr->name, cptr->fd); |
82 | cptr->flags |= CF_DEAD; |
82 | cptr->flags |= connection_t::CF_DEAD; |
83 | } |
83 | } |
84 | return; |
84 | return; |
85 | } |
85 | } |
86 | |
86 | |
87 | sq->firstused += l; |
87 | sq->firstused += l; |
… | |
… | |
97 | sq->firstused = sq->firstfree = 0; |
97 | sq->firstused = sq->firstfree = 0; |
98 | } |
98 | } |
99 | else |
99 | else |
100 | return; |
100 | return; |
101 | } |
101 | } |
102 | if (cptr->flags & CF_SEND_EOF) |
102 | if (cptr->flags & connection_t::CF_SEND_EOF) |
103 | { |
103 | { |
104 | /* shut down write end, kill entire connection |
104 | /* shut down write end, kill entire connection |
105 | * * only when the other side acknowledges -- jilles */ |
105 | * * only when the other side acknowledges -- jilles */ |
106 | #ifdef SHUT_WR |
106 | #ifdef SHUT_WR |
107 | shutdown (cptr->fd, SHUT_WR); |
107 | shutdown (cptr->fd, SHUT_WR); |
108 | #else |
108 | #else |
109 | shutdown (cptr->fd, 1); |
109 | shutdown (cptr->fd, 1); |
110 | #endif |
110 | #endif |
111 | cptr->flags |= CF_SEND_DEAD; |
111 | cptr->flags |= connection_t::CF_SEND_DEAD; |
112 | } |
112 | } |
113 | } |
113 | } |
114 | |
114 | |
115 | bool |
115 | bool |
116 | sendq_nonempty (connection_t *cptr) |
116 | sendq_nonempty (connection_t *cptr) |
117 | { |
117 | { |
118 | packetqueue *sq; |
118 | packetqueue *sq; |
119 | |
119 | |
120 | if (cptr->flags & CF_SEND_DEAD) |
120 | if (cptr->flags & connection_t::CF_SEND_DEAD) |
121 | return false; |
121 | return false; |
122 | if (cptr->flags & CF_SEND_EOF) |
122 | if (cptr->flags & connection_t::CF_SEND_EOF) |
123 | return true; |
123 | return true; |
124 | if (cptr->sendq.empty ()) |
124 | if (cptr->sendq.empty ()) |
125 | return false; |
125 | return false; |
126 | sq = cptr->sendq.front (); |
126 | sq = cptr->sendq.front (); |
127 | return sq->firstfree > sq->firstused; |
127 | return sq->firstfree > sq->firstused; |
… | |
… | |
149 | recvq_put (connection_t *cptr) |
149 | recvq_put (connection_t *cptr) |
150 | { |
150 | { |
151 | packetqueue *sq = NULL; |
151 | packetqueue *sq = NULL; |
152 | int l, ll; |
152 | int l, ll; |
153 | |
153 | |
154 | if (cptr->flags & (CF_DEAD | CF_SEND_DEAD)) |
154 | if (cptr->flags & (connection_t::CF_DEAD | connection_t::CF_SEND_DEAD)) |
155 | { |
155 | { |
156 | /* If CF_SEND_DEAD: |
156 | /* If CF_SEND_DEAD: |
157 | * The client closed the connection or sent some |
157 | * The client closed the connection or sent some |
158 | * data we don't care about, be done with it. |
158 | * data we don't care about, be done with it. |
159 | * If CF_DEAD: |
159 | * If CF_DEAD: |
160 | * Connection died earlier, be done with it now. |
160 | * Connection died earlier, be done with it now. |
161 | * -- jilles |
161 | * -- jilles |
162 | */ |
162 | */ |
163 | errno = 0; |
163 | errno = 0; |
164 | connection_close (cptr); |
164 | cptr->close (); |
165 | return; |
165 | return; |
166 | } |
166 | } |
167 | |
167 | |
168 | if (!cptr->recvq.empty ()) |
168 | if (!cptr->recvq.empty ()) |
169 | { |
169 | { |
… | |
… | |
186 | { |
186 | { |
187 | if (l == 0) |
187 | if (l == 0) |
188 | slog (LG_INFO, "recvq_put(): fd %d closed the connection", cptr->fd); |
188 | slog (LG_INFO, "recvq_put(): fd %d closed the connection", cptr->fd); |
189 | else |
189 | else |
190 | slog (LG_INFO, "recvq_put(): lost connection on fd %d", cptr->fd); |
190 | slog (LG_INFO, "recvq_put(): lost connection on fd %d", cptr->fd); |
191 | connection_close (cptr); |
191 | cptr->close (); |
192 | return; |
192 | return; |
193 | } |
193 | } |
194 | else if (l > 0) |
194 | else if (l > 0) |
195 | sq->firstfree += l; |
195 | sq->firstfree += l; |
196 | |
196 | |
… | |
… | |
268 | } |
268 | } |
269 | |
269 | |
270 | if (newline == NULL && l < len) |
270 | if (newline == NULL && l < len) |
271 | return 0; |
271 | return 0; |
272 | |
272 | |
273 | cptr->flags |= CF_NONEWLINE; |
273 | cptr->flags |= connection_t::CF_NONEWLINE; |
274 | while (!cptr->recvq.empty ()) |
274 | while (!cptr->recvq.empty ()) |
275 | { |
275 | { |
276 | sq = cptr->recvq.front (); |
276 | sq = cptr->recvq.front (); |
277 | |
277 | |
278 | if (sq->firstused == sq->firstfree || len <= 0) |
278 | if (sq->firstused == sq->firstfree || len <= 0) |
… | |
… | |
280 | |
280 | |
281 | l = sq->firstfree - sq->firstused; |
281 | l = sq->firstfree - sq->firstused; |
282 | if (l > len) |
282 | if (l > len) |
283 | l = len; |
283 | l = len; |
284 | if (sq == sq2 && l >= newline - sq->buf - sq->firstused + 1) |
284 | if (sq == sq2 && l >= newline - sq->buf - sq->firstused + 1) |
285 | cptr->flags &= ~CF_NONEWLINE, l = newline - sq->buf - sq->firstused + 1; |
285 | cptr->flags &= ~connection_t::CF_NONEWLINE, l = newline - sq->buf - sq->firstused + 1; |
286 | memcpy (p, sq->buf + sq->firstused, l); |
286 | memcpy (p, sq->buf + sq->firstused, l); |
287 | |
287 | |
288 | p += l; |
288 | p += l; |
289 | len -= l; |
289 | len -= l; |
290 | sq->firstused += l; |
290 | sq->firstused += l; |