Mercurial > pidgin
annotate src/protocols/oscar/rxqueue.c @ 10812:d087e928ffd1
[gaim-migrate @ 12465]
" A variety of spacing normalization I've done as I've
navigated the source making other changes. The specific
changes should be uncontroversial. I'm submitting these to
shrink the deltas between my local tree and the CVS
source. If spacing changes are unwelcome as a general
rule, let me know." --rlaager
I said not to do this sort of patch often.
also a spelling fix.
committer: Tailor Script <tailor@pidgin.im>
author | Luke Schierer <lschiere@pidgin.im> |
---|---|
date | Mon, 11 Apr 2005 04:32:26 +0000 |
parents | 361c9170d8af |
children | 751de30689ef |
rev | line source |
---|---|
2086 | 1 /* |
2 * This file contains the management routines for the receive | |
3 * (incoming packet) queue. The actual packet handlers are in | |
8880 | 4 * rxhandlers.c. |
2086 | 5 */ |
6 | |
7 #define FAIM_INTERNAL | |
10267 | 8 #include <aim.h> |
2086 | 9 |
10 #ifndef _WIN32 | |
11 #include <sys/socket.h> | |
12 #endif | |
13 | |
14 /* | |
15 * | |
16 */ | |
17 faim_internal int aim_recv(int fd, void *buf, size_t count) | |
18 { | |
10267 | 19 int left, cur; |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
20 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
21 for (cur = 0, left = count; left; ) { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
22 int ret; |
10267 | 23 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
24 ret = recv(fd, ((unsigned char *)buf)+cur, left, 0); |
2808
e79f30457998
[gaim-migrate @ 2821]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2706
diff
changeset
|
25 |
e79f30457998
[gaim-migrate @ 2821]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2706
diff
changeset
|
26 /* Of course EOF is an error, only morons disagree with that. */ |
e79f30457998
[gaim-migrate @ 2821]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2706
diff
changeset
|
27 if (ret <= 0) |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
28 return -1; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
29 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
30 cur += ret; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
31 left -= ret; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
32 } |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
33 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
34 return cur; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
35 } |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
36 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
37 /* |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
38 * Read into a byte stream. Will not read more than count, but may read |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
39 * less if there is not enough room in the stream buffer. |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
40 */ |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
41 faim_internal int aim_bstream_recv(aim_bstream_t *bs, int fd, size_t count) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
42 { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
43 int red = 0; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
44 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
45 if (!bs || (fd < 0) || (count < 0)) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
46 return -1; |
10267 | 47 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
48 if (count > (bs->len - bs->offset)) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
49 count = bs->len - bs->offset; /* truncate to remaining space */ |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
50 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
51 if (count) { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
52 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
53 red = aim_recv(fd, bs->data + bs->offset, count); |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
54 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
55 if (red <= 0) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
56 return -1; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
57 } |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
58 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
59 bs->offset += red; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
60 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
61 return red; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
62 } |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
63 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
64 /** |
7806 | 65 * Free an aim_frame_t |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
66 * |
7806 | 67 * @param frame The frame to free. |
68 * @return -1 on error; 0 on success. | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
69 */ |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
70 faim_internal void aim_frame_destroy(aim_frame_t *frame) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
71 { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
72 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
73 free(frame->data.data); /* XXX aim_bstream_free */ |
3952 | 74 free(frame); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
75 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
76 return; |
3952 | 77 } |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
78 |
2086 | 79 /* |
7806 | 80 * Read a FLAP header from conn into fr, and return the number of |
81 * bytes in the payload. | |
82 * | |
83 * @return -1 on error, otherwise return the length of the payload. | |
2086 | 84 */ |
5414 | 85 static int aim_get_command_flap(aim_session_t *sess, aim_conn_t *conn, aim_frame_t *fr) |
2086 | 86 { |
7806 | 87 fu8_t hdr_raw[6]; |
88 aim_bstream_t hdr; | |
10267 | 89 |
7806 | 90 fr->hdrtype = AIM_FRAMETYPE_FLAP; |
2086 | 91 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
92 /* |
7806 | 93 * Read FLAP header. Six bytes total. |
94 * | |
95 * Byte # | Description | |
96 * -------|------------- | |
97 * 0x00 | Always 0x2a | |
98 * 0x01 | Channel number, usually "2." "1" is used during login, | |
99 * | 4 is used during logoff. | |
100 * 0x02 | Sequence number, 2 bytes. | |
101 * 0x04 | Number of data bytes that follow, 2 bytes. | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
102 */ |
7806 | 103 aim_bstream_init(&hdr, hdr_raw, sizeof(hdr_raw)); |
104 if (aim_bstream_recv(&hdr, conn->fd, 6) < 6) { | |
10271 | 105 aim_conn_close(conn); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
106 return -1; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
107 } |
2086 | 108 |
7806 | 109 aim_bstream_rewind(&hdr); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
110 |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
111 /* |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
112 * This shouldn't happen unless the socket breaks, the server breaks, |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
113 * or we break. We must handle it just in case. |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
114 */ |
7806 | 115 if (aimbs_get8(&hdr) != 0x2a) { |
116 faimdprintf(sess, 0, "Invalid FLAP frame received on FLAP connection!"); | |
10271 | 117 aim_conn_close(conn); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
118 return -1; |
10267 | 119 } |
2086 | 120 |
7806 | 121 fr->hdr.flap.channel = aimbs_get8(&hdr); |
122 fr->hdr.flap.seqnum = aimbs_get16(&hdr); | |
3952 | 123 |
7806 | 124 return aimbs_get16(&hdr); |
3952 | 125 } |
126 | |
127 /* | |
7806 | 128 * Read a rendezvous header from conn into fr, and return the number of |
129 * bytes in the payload. | |
130 * | |
131 * @return -1 on error, otherwise return the length of the payload. | |
3952 | 132 */ |
133 static int aim_get_command_rendezvous(aim_session_t *sess, aim_conn_t *conn, aim_frame_t *fr) | |
134 { | |
7806 | 135 fu8_t hdr_raw[8]; |
136 aim_bstream_t hdr; | |
137 | |
138 fr->hdrtype = AIM_FRAMETYPE_OFT; | |
3952 | 139 |
7806 | 140 /* |
141 * Read rendezvous header | |
142 */ | |
143 aim_bstream_init(&hdr, hdr_raw, sizeof(hdr_raw)); | |
144 if (aim_bstream_recv(&hdr, conn->fd, 8) < 8) { | |
10271 | 145 aim_conn_close(conn); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
146 return -1; |
3952 | 147 } |
148 | |
7806 | 149 aim_bstream_rewind(&hdr); |
3952 | 150 |
7806 | 151 aimbs_getrawbuf(&hdr, fr->hdr.rend.magic, 4); |
152 fr->hdr.rend.hdrlen = aimbs_get16(&hdr); | |
153 fr->hdr.rend.type = aimbs_get16(&hdr); | |
3952 | 154 |
7806 | 155 return fr->hdr.rend.hdrlen - 8; |
3952 | 156 } |
2086 | 157 |
3952 | 158 /* |
159 * Grab a single command sequence off the socket, and enqueue it in the incoming event queue | |
160 * in a separate struct. | |
7806 | 161 * |
162 * @return 0 on success, otherwise return the error number. | |
3952 | 163 */ |
164 faim_export int aim_get_command(aim_session_t *sess, aim_conn_t *conn) | |
165 { | |
7806 | 166 aim_frame_t *fr; |
167 int payloadlen; | |
3952 | 168 |
169 if (!sess || !conn) | |
4617 | 170 return -EINVAL; |
3952 | 171 |
172 if (conn->fd == -1) | |
173 return -1; /* it's an aim_conn_close()'d connection */ | |
174 | |
175 if (conn->fd < 3) /* can happen when people abuse the interface */ | |
176 return -1; | |
177 | |
178 if (conn->status & AIM_CONN_STATUS_INPROGRESS) | |
179 return aim_conn_completeconnect(sess, conn); | |
180 | |
7806 | 181 if (!(fr = (aim_frame_t *)calloc(sizeof(aim_frame_t), 1))) |
4617 | 182 return -ENOMEM; |
3952 | 183 |
184 /* | |
185 * Rendezvous (client to client) connections do not speak FLAP, so this | |
186 * function will break on them. | |
187 */ | |
7806 | 188 if (conn->type == AIM_CONN_TYPE_RENDEZVOUS) |
189 payloadlen = aim_get_command_rendezvous(sess, conn, fr); | |
190 else if (conn->type == AIM_CONN_TYPE_LISTENER) { | |
191 faimdprintf(sess, 0, "AIM_CONN_TYPE_LISTENER on fd %d\n", conn->fd); | |
192 free(fr); | |
193 return -1; | |
194 } else | |
195 payloadlen = aim_get_command_flap(sess, conn, fr); | |
5927 | 196 |
7806 | 197 if (payloadlen < 0) { |
198 free(fr); | |
199 return -1; | |
200 } | |
201 | |
202 if (payloadlen > 0) { | |
203 fu8_t *payload = NULL; | |
204 | |
205 if (!(payload = (fu8_t *) malloc(payloadlen))) { | |
206 aim_frame_destroy(fr); | |
5927 | 207 return -1; |
208 } | |
209 | |
7806 | 210 aim_bstream_init(&fr->data, payload, payloadlen); |
2086 | 211 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
212 /* read the payload */ |
7806 | 213 if (aim_bstream_recv(&fr->data, conn->fd, payloadlen) < payloadlen) { |
214 aim_frame_destroy(fr); /* free's payload */ | |
10271 | 215 aim_conn_close(conn); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
216 return -1; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
217 } |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
218 } else |
7806 | 219 aim_bstream_init(&fr->data, NULL, 0); |
2086 | 220 |
7806 | 221 aim_bstream_rewind(&fr->data); |
2086 | 222 |
7806 | 223 fr->conn = conn; |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
224 |
7806 | 225 /* Enqueue this puppy */ |
226 fr->next = NULL; /* this will always be at the bottom */ | |
227 if (sess->queue_incoming == NULL) | |
228 sess->queue_incoming = fr; | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
229 else { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
230 aim_frame_t *cur; |
7806 | 231 for (cur = sess->queue_incoming; cur->next; cur = cur->next); |
232 cur->next = fr; | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
233 } |
2086 | 234 |
7806 | 235 fr->conn->lastactivity = time(NULL); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
236 |
10267 | 237 return 0; |
2086 | 238 } |
239 | |
240 /* | |
8735
92cbf9713795
[gaim-migrate @ 9490]
Christian Hammond <chipx86@chipx86.com>
parents:
7806
diff
changeset
|
241 * Purge receive queue of all handled commands (->handled==1). |
2086 | 242 * |
243 */ | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
244 faim_export void aim_purge_rxqueue(aim_session_t *sess) |
2086 | 245 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
246 aim_frame_t *cur, **prev; |
2086 | 247 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
248 for (prev = &sess->queue_incoming; (cur = *prev); ) { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
249 if (cur->handled) { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
250 *prev = cur->next; |
7806 | 251 aim_frame_destroy(cur); |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
252 } else |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
253 prev = &cur->next; |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
254 } |
2086 | 255 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
256 return; |
2086 | 257 } |
258 | |
259 /* | |
260 * Since aim_get_command will aim_conn_kill dead connections, we need | |
261 * to clean up the rxqueue of unprocessed connections on that socket. | |
262 * | |
263 * XXX: this is something that was handled better in the old connection | |
264 * handling method, but eh. | |
265 */ | |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
266 faim_internal void aim_rxqueue_cleanbyconn(aim_session_t *sess, aim_conn_t *conn) |
2086 | 267 { |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
268 aim_frame_t *currx; |
2086 | 269 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
270 for (currx = sess->queue_incoming; currx; currx = currx->next) { |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
271 if ((!currx->handled) && (currx->conn == conn)) |
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
272 currx->handled = 1; |
10267 | 273 } |
7806 | 274 |
2246
933346315b9b
[gaim-migrate @ 2256]
Eric Warmenhoven <eric@warmenhoven.org>
parents:
2086
diff
changeset
|
275 return; |
2086 | 276 } |