diff --git a/reactos/lib/drivers/ip/transport/tcp/event.c b/reactos/lib/drivers/ip/transport/tcp/event.c index e9c6605eb5c..a2d632e944e 100644 --- a/reactos/lib/drivers/ip/transport/tcp/event.c +++ b/reactos/lib/drivers/ip/transport/tcp/event.c @@ -383,6 +383,7 @@ TCPSendEventHandler(void *arg, u16_t space) PIRP Irp; NTSTATUS Status; PMDL Mdl; + ULONG BytesSent; ReferenceObject(Connection); @@ -412,9 +413,9 @@ TCPSendEventHandler(void *arg, u16_t space) Status = TCPTranslateError(LibTCPSend(Connection, SendBuffer, - SendLen, TRUE)); + SendLen, &BytesSent, TRUE)); - TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", SendLen)); + TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", BytesSent)); if( Status == STATUS_PENDING ) { @@ -430,7 +431,7 @@ TCPSendEventHandler(void *arg, u16_t space) Bucket->Request, Status)); Bucket->Status = Status; - Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? SendLen : 0; + Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? BytesSent : 0; CompleteBucket(Connection, Bucket, FALSE); } diff --git a/reactos/lib/drivers/ip/transport/tcp/tcp.c b/reactos/lib/drivers/ip/transport/tcp/tcp.c index dc1940aa24b..d29e93c2f0e 100644 --- a/reactos/lib/drivers/ip/transport/tcp/tcp.c +++ b/reactos/lib/drivers/ip/transport/tcp/tcp.c @@ -544,6 +544,7 @@ NTSTATUS TCPSendData Status = TCPTranslateError(LibTCPSend(Connection, BufferData, SendLength, + BytesSent, FALSE)); TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Send: %x, %d\n", Status, SendLength)); @@ -562,19 +563,10 @@ NTSTATUS TCPSendData Bucket->Request.RequestNotifyObject = Complete; Bucket->Request.RequestContext = Context; - *BytesSent = 0; InsertTailList( &Connection->SendRequest, &Bucket->Entry ); TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Queued write irp\n")); } - else if (Status == STATUS_SUCCESS) - { - *BytesSent = SendLength; - } - else - { - *BytesSent = 0; - } UnlockObject(Connection, OldIrql); diff --git a/reactos/lib/drivers/lwip/src/include/rosip.h b/reactos/lib/drivers/lwip/src/include/rosip.h index 37f0883a87d..9fa2b16cc3a 100755 --- a/reactos/lib/drivers/lwip/src/include/rosip.h +++ b/reactos/lib/drivers/lwip/src/include/rosip.h @@ -72,6 +72,7 @@ struct lwip_callback_msg } Listen; struct { err_t Error; + u32_t Information; } Send; struct { err_t Error; @@ -98,7 +99,7 @@ extern void TCPRecvEventHandler(void *arg); PTCP_PCB LibTCPSocket(void *arg); err_t LibTCPBind(PCONNECTION_ENDPOINT Connection, struct ip_addr *const ipaddr, const u16_t port); PTCP_PCB LibTCPListen(PCONNECTION_ENDPOINT Connection, const u8_t backlog); -err_t LibTCPSend(PCONNECTION_ENDPOINT Connection, void *const dataptr, const u16_t len, const int safe); +err_t LibTCPSend(PCONNECTION_ENDPOINT Connection, void *const dataptr, const u16_t len, u32_t *sent, const int safe); err_t LibTCPConnect(PCONNECTION_ENDPOINT Connection, struct ip_addr *const ipaddr, const u16_t port); err_t LibTCPShutdown(PCONNECTION_ENDPOINT Connection, const int shut_rx, const int shut_tx); err_t LibTCPClose(PCONNECTION_ENDPOINT Connection, const int safe, const int callback); diff --git a/reactos/lib/drivers/lwip/src/rostcp.c b/reactos/lib/drivers/lwip/src/rostcp.c index a85a70386bf..005f62eb7bf 100755 --- a/reactos/lib/drivers/lwip/src/rostcp.c +++ b/reactos/lib/drivers/lwip/src/rostcp.c @@ -443,6 +443,9 @@ void LibTCPSendCallback(void *arg) { struct lwip_callback_msg *msg = arg; + PTCP_PCB pcb = msg->Input.Send.Connection->SocketContext; + ULONG SendLength; + UCHAR SendFlags; ASSERT(msg); @@ -458,19 +461,37 @@ LibTCPSendCallback(void *arg) goto done; } - msg->Output.Send.Error = tcp_write((PTCP_PCB)msg->Input.Send.Connection->SocketContext, - msg->Input.Send.Data, - msg->Input.Send.DataLength, - TCP_WRITE_FLAG_COPY); - if (msg->Output.Send.Error == ERR_MEM) + SendFlags = TCP_WRITE_FLAG_COPY; + SendLength = msg->Input.Send.DataLength; + if (tcp_sndbuf(pcb) == 0) { /* No buffer space so return pending */ msg->Output.Send.Error = ERR_INPROGRESS; + goto done; } - else if (msg->Output.Send.Error == ERR_OK) + else if (tcp_sndbuf(pcb) < SendLength) + { + /* We've got some room so let's send what we can */ + SendLength = tcp_sndbuf(pcb); + + /* Don't set the push flag */ + SendFlags |= TCP_WRITE_FLAG_MORE; + } + + msg->Output.Send.Error = tcp_write(pcb, + msg->Input.Send.Data, + SendLength, + SendFlags); + if (msg->Output.Send.Error == ERR_OK) { /* Queued successfully so try to send it */ tcp_output((PTCP_PCB)msg->Input.Send.Connection->SocketContext); + msg->Output.Send.Information = SendLength; + } + else if (msg->Output.Send.Error == ERR_MEM) + { + /* The queue is too long */ + msg->Output.Send.Error = ERR_INPROGRESS; } done: @@ -478,7 +499,7 @@ done: } err_t -LibTCPSend(PCONNECTION_ENDPOINT Connection, void *const dataptr, const u16_t len, const int safe) +LibTCPSend(PCONNECTION_ENDPOINT Connection, void *const dataptr, const u16_t len, u32_t *sent, const int safe) { err_t ret; struct lwip_callback_msg *msg; @@ -501,6 +522,11 @@ LibTCPSend(PCONNECTION_ENDPOINT Connection, void *const dataptr, const u16_t len else ret = ERR_CLSD; + if (ret == ERR_OK) + *sent = msg->Output.Send.Information; + else + *sent = 0; + ExFreeToNPagedLookasideList(&MessageLookasideList, msg); return ret;