| 201 static void |
201 static void |
| 202 peer_proxy_connection_recv_cb(gpointer data, gint source, GaimInputCondition cond) |
202 peer_proxy_connection_recv_cb(gpointer data, gint source, GaimInputCondition cond) |
| 203 { |
203 { |
| 204 PeerConnection *conn; |
204 PeerConnection *conn; |
| 205 ssize_t read; |
205 ssize_t read; |
| 206 guint8 header[12]; |
|
| 207 ProxyFrame *frame; |
206 ProxyFrame *frame; |
| 208 |
207 |
| 209 conn = data; |
208 conn = data; |
| 210 frame = conn->frame; |
209 frame = conn->frame; |
| 211 |
210 |
| 212 /* Start reading a new proxy frame */ |
211 /* Start reading a new proxy frame */ |
| 213 if (frame == NULL) |
212 if (frame == NULL) |
| 214 { |
213 { |
| 215 /* Peek at the first 12 bytes to get the length */ |
214 /* Read the first 12 bytes (frame length and header) */ |
| 216 read = recv(conn->fd, &header, 12, MSG_PEEK); |
215 read = recv(conn->fd, conn->proxy_header + conn->proxy_header_received, |
| |
216 12 - conn->proxy_header_received, 0); |
| 217 |
217 |
| 218 /* Check if the proxy server closed the connection */ |
218 /* Check if the proxy server closed the connection */ |
| 219 if (read == 0) |
219 if (read == 0) |
| 220 { |
220 { |
| 221 gaim_debug_info("oscar", "Peer proxy server closed connection\n"); |
221 gaim_debug_info("oscar", "Peer proxy server closed connection\n"); |
| 236 } |
236 } |
| 237 |
237 |
| 238 conn->lastactivity = time(NULL); |
238 conn->lastactivity = time(NULL); |
| 239 |
239 |
| 240 /* If we don't even have the first 12 bytes then do nothing */ |
240 /* If we don't even have the first 12 bytes then do nothing */ |
| 241 if (read < 12) |
241 conn->proxy_header_received += read; |
| 242 return; |
242 if (conn->proxy_header_received < 12) |
| 243 |
243 return; |
| 244 /* Read the first 12 bytes (frame length and header) */ |
|
| 245 read = recv(conn->fd, &header, 12, 0); |
|
| 246 |
244 |
| 247 /* We only support a specific version of the proxy protocol */ |
245 /* We only support a specific version of the proxy protocol */ |
| 248 if (aimutil_get16(&header[2]) != PEER_PROXY_PACKET_VERSION) |
246 if (aimutil_get16(&conn->proxy_header[2]) != PEER_PROXY_PACKET_VERSION) |
| 249 { |
247 { |
| 250 gaim_debug_warning("oscar", "Expected peer proxy protocol " |
248 gaim_debug_warning("oscar", "Expected peer proxy protocol " |
| 251 "version %u but received version %u. Closing " |
249 "version %u but received version %u. Closing " |
| 252 "connection.\n", PEER_PROXY_PACKET_VERSION, |
250 "connection.\n", PEER_PROXY_PACKET_VERSION, |
| 253 aimutil_get16(&header[2])); |
251 aimutil_get16(&conn->proxy_header[2])); |
| 254 peer_connection_trynext(conn); |
252 peer_connection_trynext(conn); |
| 255 return; |
253 return; |
| 256 } |
254 } |
| 257 |
255 |
| 258 /* Initialize a new temporary ProxyFrame for incoming data */ |
256 /* Initialize a new temporary ProxyFrame for incoming data */ |
| 259 frame = g_new0(ProxyFrame, 1); |
257 frame = g_new0(ProxyFrame, 1); |
| 260 frame->payload.len = aimutil_get16(&header[0]) - 10; |
258 frame->payload.len = aimutil_get16(&conn->proxy_header[0]) - 10; |
| 261 frame->version = aimutil_get16(&header[2]); |
259 frame->version = aimutil_get16(&conn->proxy_header[2]); |
| 262 frame->type = aimutil_get16(&header[4]); |
260 frame->type = aimutil_get16(&conn->proxy_header[4]); |
| 263 frame->unknown = aimutil_get16(&header[6]); |
261 frame->unknown = aimutil_get16(&conn->proxy_header[6]); |
| 264 frame->flags = aimutil_get16(&header[10]); |
262 frame->flags = aimutil_get16(&conn->proxy_header[10]); |
| 265 if (frame->payload.len > 0) |
263 if (frame->payload.len > 0) |
| 266 frame->payload.data = g_new(guint8, frame->payload.len); |
264 frame->payload.data = g_new(guint8, frame->payload.len); |
| 267 conn->frame = frame; |
265 conn->frame = frame; |
| 268 } |
266 } |
| 269 |
267 |
| 311 |
309 |
| 312 /* We have a complete proxy frame! Handle it and continue reading */ |
310 /* We have a complete proxy frame! Handle it and continue reading */ |
| 313 conn->frame = NULL; |
311 conn->frame = NULL; |
| 314 byte_stream_rewind(&frame->payload); |
312 byte_stream_rewind(&frame->payload); |
| 315 peer_proxy_recv_frame(conn, frame); |
313 peer_proxy_recv_frame(conn, frame); |
| |
314 |
| 316 g_free(frame->payload.data); |
315 g_free(frame->payload.data); |
| 317 g_free(frame); |
316 g_free(frame); |
| |
317 |
| |
318 conn->proxy_header_received = 0; |
| 318 } |
319 } |
| 319 |
320 |
| 320 /** |
321 /** |
| 321 * We tried to make an outgoing connection to a proxy server. It |
322 * We tried to make an outgoing connection to a proxy server. It |
| 322 * either connected or failed to connect. |
323 * either connected or failed to connect. |