changeset 15195:4934e7a03a98

[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 <tailor@pidgin.im>
author Mark Doliner <mark@kingant.net>
date Wed, 13 Dec 2006 10:11:31 +0000
parents 8d2e6e9118e2
children ee79c2c1b5ac
files libgaim/protocols/oscar/flap_connection.c libgaim/protocols/oscar/oscar.h libgaim/protocols/oscar/peer.c libgaim/protocols/oscar/peer.h libgaim/protocols/oscar/peer_proxy.c
diffstat 5 files changed, 48 insertions(+), 41 deletions(-) [+]
line wrap: on
line diff
--- 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;
 	}
 }
 
--- 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;
--- 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;
 }
 
 /*******************************************************************/
--- 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.
 	 */
--- 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;
 }
 
 /**