- 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); DereferenceObject(Connection);
} }
u32_t VOID
TCPRecvEventHandler(void *arg, struct pbuf *p) TCPRecvEventHandler(void *arg)
{ {
PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg; PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg;
PTDI_BUCKET Bucket; PTDI_BUCKET Bucket;
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
PIRP Irp; PIRP Irp;
PMDL Mdl; PMDL Mdl;
UINT Received = 0; UINT Received;
UINT RecvLen; UINT RecvLen;
PUCHAR RecvBuffer; PUCHAR RecvBuffer;
NTSTATUS Status;
ASSERT(p);
ReferenceObject(Connection); ReferenceObject(Connection);
if ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock))) while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock)))
{ {
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry ); Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
Irp = Bucket->Request.RequestContext; Irp = Bucket->Request.RequestContext;
Mdl = Irp->MdlAddress; Mdl = Irp->MdlAddress;
TI_DbgPrint(DEBUG_TCP,
("[IP, TCPRecvEventHandler] Getting the user buffer from %x\n", Mdl));
NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen ); NdisQueryBuffer( Mdl, &RecvBuffer, &RecvLen );
TI_DbgPrint(DEBUG_TCP, Status = LibTCPGetDataFromConnectionQueue(Connection, RecvBuffer, RecvLen, &Received);
("[IP, TCPRecvEventHandler] Reading %d bytes to %x\n", RecvLen, RecvBuffer)); if (Status == STATUS_PENDING)
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)
{ {
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;
Bucket->Status = STATUS_SUCCESS;
Bucket->Information = Received; Bucket->Information = Received;
CompleteBucket(Connection, Bucket, FALSE); CompleteBucket(Connection, Bucket, FALSE);
} }
DereferenceObject(Connection); DereferenceObject(Connection);
return Received;
} }
VOID 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 TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb);
extern void TCPSendEventHandler(void *arg, const u16_t space); extern void TCPSendEventHandler(void *arg, const u16_t space);
extern void TCPFinEventHandler(void *arg, const err_t err); 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 */ /* TCP functions */
PTCP_PCB LibTCPSocket(void *arg); 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; return ERR_OK;
} }
ASSERT(!LibTCPDequeuePacket(Connection));
if (p) if (p)
{ {
len = TCPRecvEventHandler(arg, p); LibTCPEnqueuePacket(Connection, p);
if (len == p->tot_len)
{
tcp_recved(pcb, len);
pbuf_free(p); tcp_recved(pcb, p->tot_len);
return ERR_OK; TCPRecvEventHandler(arg);
}
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;
}
} }
else if (err == ERR_OK) else if (err == ERR_OK)
{ {