- Rewrite receive code to make it much simpler, handle some corner cases that weren't treated correctly, and fix the data corruption bug
- Downloaded successfully (no data corruption): OpenOffice 2.4, OpenOffice 3.3, BitTorrent 7.2.1, Firefox 5, Firefox 3.6, Firefox 3, Firefox 2, Abyss Web Server, Opera 9.64, and Opera 11.01

svn path=/trunk/; revision=53189
This commit is contained in:
Cameron Gutman 2011-08-11 21:52:41 +00:00
parent 6fbcf9c9ea
commit 2218bdc6ab
3 changed files with 22 additions and 59 deletions

View file

@ -451,59 +451,46 @@ TCPSendEventHandler(void *arg, u16_t space)
DereferenceObject(Connection);
}
u32_t
TCPRecvEventHandler(void *arg, struct pbuf *p)
VOID
TCPRecvEventHandler(void *arg)
{
PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg;
PTDI_BUCKET Bucket;
PLIST_ENTRY Entry;
PIRP Irp;
PMDL Mdl;
UINT Received = 0;
UINT Received;
UINT RecvLen;
PUCHAR RecvBuffer;
ASSERT(p);
NTSTATUS Status;
ReferenceObject(Connection);
if ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock)))
while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock)))
{
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Irp = Bucket->Request.RequestContext;
Mdl = Irp->MdlAddress;
TI_DbgPrint(DEBUG_TCP,
("[IP, TCPRecvEventHandler] Getting the user buffer from %x\n", Mdl));
NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
TI_DbgPrint(DEBUG_TCP,
("[IP, TCPRecvEventHandler] Reading %d bytes to %x\n", RecvLen, RecvBuffer));
TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
TI_DbgPrint(DEBUG_TCP, ("[IP, TCPRecvEventHandler] Connection->SocketContext: %x\n", Connection->SocketContext));
TI_DbgPrint(DEBUG_TCP, ("[IP, TCPRecvEventHandler] RecvBuffer: %x\n", RecvBuffer));
RecvLen = MIN(p->tot_len, RecvLen);
for (Received = 0; Received < RecvLen; Received += p->len, p = p->next)
Status = LibTCPGetDataFromConnectionQueue(Connection, RecvBuffer, RecvLen, &Received);
if (Status == STATUS_PENDING)
{
RtlCopyMemory(RecvBuffer + Received, p->payload, p->len);
ExInterlockedInsertHeadList(&Connection->ReceiveRequest,
&Bucket->Entry,
&Connection->Lock);
break;
}
TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
Bucket->Status = STATUS_SUCCESS;
Bucket->Status = Status;
Bucket->Information = Received;
CompleteBucket(Connection, Bucket, FALSE);
}
DereferenceObject(Connection);
return Received;
}
VOID

View file

@ -91,7 +91,7 @@ extern void TCPConnectEventHandler(void *arg, const err_t err);
extern void TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb);
extern void TCPSendEventHandler(void *arg, const u16_t space);
extern void TCPFinEventHandler(void *arg, const err_t err);
extern u32_t TCPRecvEventHandler(void *arg, struct pbuf *p);
extern void TCPRecvEventHandler(void *arg);
/* TCP functions */
PTCP_PCB LibTCPSocket(void *arg);

View file

@ -207,37 +207,13 @@ InternalRecvEventHandler(void *arg, PTCP_PCB pcb, struct pbuf *p, const err_t er
return ERR_OK;
}
ASSERT(!LibTCPDequeuePacket(Connection));
if (p)
{
len = TCPRecvEventHandler(arg, p);
if (len == p->tot_len)
{
tcp_recved(pcb, len);
LibTCPEnqueuePacket(Connection, p);
pbuf_free(p);
tcp_recved(pcb, p->tot_len);
return ERR_OK;
}
else if (len != 0)
{
DbgPrint("UNTESTED CASE: NOT ALL DATA TAKEN! EXTRA DATA MAY BE LOST!\n");
tcp_recved(pcb, len);
/* Possible memory leak of pbuf here? */
return ERR_OK;
}
else
{
LibTCPEnqueuePacket(Connection, p);
tcp_recved(pcb, p->tot_len);
return ERR_OK;
}
TCPRecvEventHandler(arg);
}
else if (err == ERR_OK)
{