# HG changeset patch # User Mark Doliner # Date 1166004691 0 # Node ID 4934e7a03a9848e1cd42e40aa48c01e226b4a573 # Parent 8d2e6e9118e24eaf58313a0f731813935c609b5d [gaim-migrate @ 17983] Move away from using MSG_PEEK when recv'ing data over oscar sockets. It's possible this was causing problems with a small number of Windows users? People seem to frown pretty heavily upon MSG_PEEK in general, for some reason. committer: Tailor Script diff -r 8d2e6e9118e2 -r 4934e7a03a98 libgaim/protocols/oscar/flap_connection.c --- a/libgaim/protocols/oscar/flap_connection.c Wed Dec 13 08:45:57 2006 +0000 +++ b/libgaim/protocols/oscar/flap_connection.c Wed Dec 13 10:11:31 2006 +0000 @@ -770,7 +770,6 @@ { FlapConnection *conn; ssize_t read; - guint8 header[6]; conn = data; @@ -780,8 +779,9 @@ /* Start reading a new FLAP */ if (conn->buffer_incoming.data.data == NULL) { - /* Peek at the first 6 bytes to get the length */ - read = recv(conn->fd, &header, 6, MSG_PEEK); + /* Read the first 6 bytes (the FLAP header) */ + read = recv(conn->fd, conn->header + conn->header_received, + 6 - conn->header_received, 0); /* Check if the FLAP server closed the connection */ if (read == 0) @@ -805,14 +805,12 @@ } /* If we don't even have a complete FLAP header then do nothing */ - if (read < 6) + conn->header_received += read; + if (conn->header_received < 6) break; - /* Read the first 6 bytes (the FLAP header) */ - read = recv(conn->fd, &header, 6, 0); - /* All FLAP frames must start with the byte 0x2a */ - if (aimutil_get8(&header[0]) != 0x2a) + if (aimutil_get8(&conn->header[0]) != 0x2a) { flap_connection_schedule_destroy(conn, OSCAR_DISCONNECT_INVALID_DATA, NULL); @@ -822,7 +820,7 @@ /* Verify the sequence number sent by the server. */ #if 0 /* TODO: Need to initialize conn->seqnum_in somewhere before we can use this. */ - if (aimutil_get16(&header[1]) != conn->seqnum_in++) + if (aimutil_get16(&conn->header[1]) != conn->seqnum_in++) { /* Received an out-of-order FLAP! */ flap_connection_schedule_destroy(conn, @@ -832,9 +830,9 @@ #endif /* Initialize a new temporary FlapFrame for incoming data */ - conn->buffer_incoming.channel = aimutil_get8(&header[1]); - conn->buffer_incoming.seqnum = aimutil_get16(&header[2]); - conn->buffer_incoming.data.len = aimutil_get16(&header[4]); + conn->buffer_incoming.channel = aimutil_get8(&conn->header[1]); + conn->buffer_incoming.seqnum = aimutil_get16(&conn->header[2]); + conn->buffer_incoming.data.len = aimutil_get16(&conn->header[4]); conn->buffer_incoming.data.data = g_new(guint8, conn->buffer_incoming.data.len); conn->buffer_incoming.data.offset = 0; } @@ -880,6 +878,8 @@ g_free(conn->buffer_incoming.data.data); conn->buffer_incoming.data.data = NULL; + + conn->header_received = 0; } } diff -r 8d2e6e9118e2 -r 4934e7a03a98 libgaim/protocols/oscar/oscar.h --- a/libgaim/protocols/oscar/oscar.h Wed Dec 13 08:45:57 2006 +0000 +++ b/libgaim/protocols/oscar/oscar.h Wed Dec 13 10:11:31 2006 +0000 @@ -382,6 +382,8 @@ gpointer new_conn_data; int fd; + guint8 header[6]; + ssize_t header_received; FlapFrame buffer_incoming; GaimCircBuffer *buffer_outgoing; guint watcher_incoming; diff -r 8d2e6e9118e2 -r 4934e7a03a98 libgaim/protocols/oscar/peer.c --- a/libgaim/protocols/oscar/peer.c Wed Dec 13 08:45:57 2006 +0000 +++ b/libgaim/protocols/oscar/peer.c Wed Dec 13 10:11:31 2006 +0000 @@ -288,15 +288,15 @@ { PeerConnection *conn; ssize_t read; - guint8 header[6]; conn = data; /* Start reading a new ODC/OFT frame */ if (conn->buffer_incoming.data == NULL) { - /* Peek at the first 6 bytes to get the length */ - read = recv(conn->fd, &header, 6, MSG_PEEK); + /* Read the first 6 bytes (magic string and frame length) */ + read = recv(conn->fd, conn->header + conn->header_received, + 6 - conn->header_received, 0); /* Check if the remote user closed the connection */ if (read == 0) @@ -320,26 +320,25 @@ conn->lastactivity = time(NULL); /* If we don't even have the first 6 bytes then do nothing */ - if (read < 6) + conn->header_received += read; + if (conn->header_received < 6) return; - /* Read the first 6 bytes (magic string and frame length) */ - read = recv(conn->fd, &header, 6, 0); - /* All ODC/OFT frames must start with a magic string */ - if (memcmp(conn->magic, header, 4)) + if (memcmp(conn->magic, conn->header, 4)) { gaim_debug_warning("oscar", "Expecting magic string to " "be %c%c%c%c but received magic string %c%c%c%c. " "Closing connection.\n", conn->magic[0], conn->magic[1], conn->magic[2], - conn->magic[3], header[0], header[1], header[2], header[3]); + conn->magic[3], conn->header[0], conn->header[1], + conn->header[2], conn->header[3]); peer_connection_destroy(conn, OSCAR_DISCONNECT_INVALID_DATA, NULL); return; } /* Initialize a new temporary ByteStream for incoming data */ - conn->buffer_incoming.len = aimutil_get16(&header[4]) - 6; + conn->buffer_incoming.len = aimutil_get16(&conn->header[4]) - 6; conn->buffer_incoming.data = g_new(guint8, conn->buffer_incoming.len); conn->buffer_incoming.offset = 0; } @@ -384,8 +383,11 @@ { peer_oft_recv_frame(conn, &conn->buffer_incoming); } + g_free(conn->buffer_incoming.data); conn->buffer_incoming.data = NULL; + + conn->header_received = 0; } /*******************************************************************/ diff -r 8d2e6e9118e2 -r 4934e7a03a98 libgaim/protocols/oscar/peer.h --- a/libgaim/protocols/oscar/peer.h Wed Dec 13 08:45:57 2006 +0000 +++ b/libgaim/protocols/oscar/peer.h Wed Dec 13 10:11:31 2006 +0000 @@ -158,7 +158,7 @@ */ GaimProxyConnectData *client_connect_data; GaimProxyConnectData *verified_connect_data; - + /** * This is only used when the peer connection is being established. */ @@ -177,13 +177,15 @@ int listenerfd; int fd; - + guint8 header[6]; + ssize_t header_received; + guint8 proxy_header[12]; + ssize_t proxy_header_received; + ByteStream buffer_incoming; + GaimCircBuffer *buffer_outgoing; guint watcher_incoming; guint watcher_outgoing; - ByteStream buffer_incoming; - GaimCircBuffer *buffer_outgoing; - /** * IP address of the proxy server, if applicable. */ diff -r 8d2e6e9118e2 -r 4934e7a03a98 libgaim/protocols/oscar/peer_proxy.c --- a/libgaim/protocols/oscar/peer_proxy.c Wed Dec 13 08:45:57 2006 +0000 +++ b/libgaim/protocols/oscar/peer_proxy.c Wed Dec 13 10:11:31 2006 +0000 @@ -203,7 +203,6 @@ { PeerConnection *conn; ssize_t read; - guint8 header[12]; ProxyFrame *frame; conn = data; @@ -212,8 +211,9 @@ /* Start reading a new proxy frame */ if (frame == NULL) { - /* Peek at the first 12 bytes to get the length */ - read = recv(conn->fd, &header, 12, MSG_PEEK); + /* Read the first 12 bytes (frame length and header) */ + read = recv(conn->fd, conn->proxy_header + conn->proxy_header_received, + 12 - conn->proxy_header_received, 0); /* Check if the proxy server closed the connection */ if (read == 0) @@ -238,30 +238,28 @@ conn->lastactivity = time(NULL); /* If we don't even have the first 12 bytes then do nothing */ - if (read < 12) + conn->proxy_header_received += read; + if (conn->proxy_header_received < 12) return; - /* Read the first 12 bytes (frame length and header) */ - read = recv(conn->fd, &header, 12, 0); - /* We only support a specific version of the proxy protocol */ - if (aimutil_get16(&header[2]) != PEER_PROXY_PACKET_VERSION) + if (aimutil_get16(&conn->proxy_header[2]) != PEER_PROXY_PACKET_VERSION) { gaim_debug_warning("oscar", "Expected peer proxy protocol " "version %u but received version %u. Closing " "connection.\n", PEER_PROXY_PACKET_VERSION, - aimutil_get16(&header[2])); + aimutil_get16(&conn->proxy_header[2])); peer_connection_trynext(conn); return; } /* Initialize a new temporary ProxyFrame for incoming data */ frame = g_new0(ProxyFrame, 1); - frame->payload.len = aimutil_get16(&header[0]) - 10; - frame->version = aimutil_get16(&header[2]); - frame->type = aimutil_get16(&header[4]); - frame->unknown = aimutil_get16(&header[6]); - frame->flags = aimutil_get16(&header[10]); + frame->payload.len = aimutil_get16(&conn->proxy_header[0]) - 10; + frame->version = aimutil_get16(&conn->proxy_header[2]); + frame->type = aimutil_get16(&conn->proxy_header[4]); + frame->unknown = aimutil_get16(&conn->proxy_header[6]); + frame->flags = aimutil_get16(&conn->proxy_header[10]); if (frame->payload.len > 0) frame->payload.data = g_new(guint8, frame->payload.len); conn->frame = frame; @@ -313,8 +311,11 @@ conn->frame = NULL; byte_stream_rewind(&frame->payload); peer_proxy_recv_frame(conn, frame); + g_free(frame->payload.data); g_free(frame); + + conn->proxy_header_received = 0; } /**