diff options
| -rw-r--r-- | dcc.c | 33 | ||||
| -rw-r--r-- | dcc.h | 6 | 
2 files changed, 20 insertions, 19 deletions
| @@ -293,35 +293,30 @@ gboolean dccs_send_proto( gpointer data, gint fd, b_input_condition cond )  	if( cond & GAIM_INPUT_READ )   	{ -		int bytes_received;  		int ret; -		ASSERTSOCKOP( ret = recv( fd, &bytes_received, sizeof( bytes_received ), MSG_PEEK ), "Receiving" ); +		ASSERTSOCKOP( ret = recv( fd, ( (char*) &df->acked ) + df->acked_len, +			sizeof( df->acked ) - df->acked_len, 0 ), "Receiving" );  		if( ret == 0 )  			return dcc_abort( df, "Remote end closed connection" ); -			 -		if( ret < 4 ) -		{ -			imcb_log( df->ic, "WARNING: DCC SEND: receiver sent only %d bytes instead of 4, shouldn't happen too often!", ret ); +		 +		/* How likely is it that a 32-bit integer gets split accross +		   packet boundaries? Chances are rarely 0 so let's be sure. */ +		if( ( df->acked_len = ( df->acked_len + ret ) % 4 ) > 0 )  			return TRUE; -		} - -		ASSERTSOCKOP( ret = recv( fd, &bytes_received, sizeof( bytes_received ), 0 ), "Receiving" ); -		if( ret != 4 ) -			return dcc_abort( df, "MSG_PEEK'ed 4, but can only dequeue %d bytes", ret ); -		bytes_received = ntohl( bytes_received ); +		df->acked = ntohl( df->acked );  		/* If any of this is actually happening, the receiver should buy a new IRC client */ -		if ( bytes_received > df->bytes_sent ) -			return dcc_abort( df, "Receiver magically received more bytes than sent ( %d > %d ) (BUG at receiver?)", bytes_received, df->bytes_sent ); +		if ( df->acked > df->bytes_sent ) +			return dcc_abort( df, "Receiver magically received more bytes than sent ( %d > %d ) (BUG at receiver?)", df->acked, df->bytes_sent ); -		if ( bytes_received < file->bytes_transferred ) -			return dcc_abort( df, "Receiver lost bytes? ( has %d, had %d ) (BUG at receiver?)", bytes_received, file->bytes_transferred ); +		if ( df->acked < file->bytes_transferred ) +			return dcc_abort( df, "Receiver lost bytes? ( has %d, had %d ) (BUG at receiver?)", df->acked, file->bytes_transferred ); -		file->bytes_transferred = bytes_received; +		file->bytes_transferred = df->acked;  		if( file->bytes_transferred >= file->file_size ) {  			if( df->proto_finished ) @@ -411,8 +406,8 @@ gboolean dccs_recv_proto( gpointer data, gint fd, b_input_condition cond )  		if( ( ( df->bytes_sent - ft->bytes_transferred ) > DCC_PACKET_SIZE ) ||  		    done )  		{ -			int ack, ackret; -			ack = htonl( ft->bytes_transferred = df->bytes_sent ); +			guint32 ack = htonl( ft->bytes_transferred = df->bytes_sent ); +			int ackret;  			ASSERTSOCKOP( ackret = send( fd, &ack, 4, 0 ), "Sending DCC ACK" ); @@ -76,6 +76,12 @@ typedef struct dcc_file_transfer {  	 */  	size_t bytes_sent; +	/* +	 * Handle the wonderful sadly-not-deprecated ACKs. +	 */ +	guint32 acked; +	int acked_len; +	  	/* imc's handle */  	file_transfer_t *ft; | 
