- Remove debug prints
- Modify error code translations
[lwIP]
- Fix race conditions caused by checking the SocketContexts of connections from outside the lwIP main thread context
- Don't explicitly remove callbacks from pcbs (no reason to do apperently)
- Use pbuf_free_callback (which can be safely called from outside the lwIP main thread context) instead of pbuf_free

svn path=/branches/GSoC_2011/TcpIpDriver/; revision=53033
This commit is contained in:
Claudiu Mihail 2011-08-02 19:20:40 +00:00
parent 95cdb2c148
commit cb01eb2af4
8 changed files with 93 additions and 392 deletions

View file

@ -20,8 +20,6 @@ NTSTATUS TCPCheckPeerForAccept(PVOID Context,
PTDI_CONNECTION_INFORMATION WhoIsConnecting;
PTA_IP_ADDRESS RemoteAddress;
struct ip_addr ipaddr;
DbgPrint("[IP, TCPCheckPeerForAccept] Called\n");
if (Request->RequestFlags & TDI_QUERY_ACCEPT)
DbgPrint("TDI_QUERY_ACCEPT NOT SUPPORTED!!!\n");
@ -39,8 +37,6 @@ NTSTATUS TCPCheckPeerForAccept(PVOID Context,
RemoteAddress->Address[0].Address[0].in_addr = ipaddr.addr;
DbgPrint("[IP, TCPCheckPeerForAccept] Leaving. Status %x\n", Status);
return Status;
}
@ -60,7 +56,6 @@ NTSTATUS TCPListen(PCONNECTION_ENDPOINT Connection, UINT Backlog)
ASSERT_KM_POINTER(Connection->AddressFile);
TI_DbgPrint(DEBUG_TCP,("[IP, TCPListen] Called\n"));
DbgPrint("[IP, TCPListen] Called\n");
TI_DbgPrint(DEBUG_TCP, ("Connection->SocketContext %x\n",
Connection->SocketContext));
@ -99,7 +94,6 @@ NTSTATUS TCPListen(PCONNECTION_ENDPOINT Connection, UINT Backlog)
UnlockObject(Connection, OldIrql);
TI_DbgPrint(DEBUG_TCP,("[IP, TCPListen] Leaving. Status = %x\n", Status));
DbgPrint("[IP, TCPListen] Leaving. Status = %x\n", Status);
return Status;
}
@ -113,8 +107,6 @@ BOOLEAN TCPAbortListenForSocket
KIRQL OldIrql;
BOOLEAN Found = FALSE;
DbgPrint("[IP, TCPAbortListenForSocket] Called\n");
LockObject(Listener, &OldIrql);
ListEntry = Listener->ListenRequest.Flink;
@ -136,9 +128,6 @@ BOOLEAN TCPAbortListenForSocket
UnlockObject(Listener, OldIrql);
DbgPrint("[IP, TCPAbortListenForSocket] Leaving. Status = %s\n",
Found == TRUE ? "TRUE" : "FALSE");
return Found;
}
@ -152,8 +141,6 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request,
PTDI_BUCKET Bucket;
KIRQL OldIrql;
DbgPrint("[IP, TCPAccept] Called\n");
LockObject(Listener, &OldIrql);
Bucket = (PTDI_BUCKET)ExAllocatePoolWithTag(NonPagedPool,
@ -175,6 +162,5 @@ NTSTATUS TCPAccept ( PTDI_REQUEST Request,
UnlockObject(Listener, OldIrql);
DbgPrint("[IP, TCPAccept] Leaving. Status = %x\n", Status);
return Status;
}

View file

@ -69,9 +69,7 @@ FlushAllQueues(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
PLIST_ENTRY Entry;
ReferenceObject(Connection);
DbgPrint("[IP, FlushAllQueues] Flushing recv/all with status: 0x%x for Connection = 0x%x\n", Status, Connection);
while ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock)))
{
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
@ -91,7 +89,6 @@ FlushAllQueues(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
//
if (Status == STATUS_SUCCESS)
{
DbgPrint("[IP, FlushAllQueues] Flushed recv only after graceful closure\n");
DereferenceObject(Connection);
return;
}
@ -102,8 +99,6 @@ FlushAllQueues(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
Bucket->Status = Status;
Bucket->Information = 0;
DbgPrint("[IP, FlushAllQueues] Completing Listen request for Connection = 0x%x\n", Bucket->AssociatedEndpoint);
DereferenceObject(Bucket->AssociatedEndpoint);
CompleteBucket(Connection, Bucket, FALSE);
@ -129,15 +124,11 @@ FlushAllQueues(PCONNECTION_ENDPOINT Connection, const NTSTATUS Status)
Bucket->Status = Status;
Bucket->Information = 0;
DbgPrint("[IP, FlushAllQueues] Completing Connection request for Connection = 0x%x\n", Bucket->AssociatedEndpoint);
CompleteBucket(Connection, Bucket, FALSE);
}
DereferenceObject(Connection);
DbgPrint("[IP, FlushAllQueues] Leaving\n");
}
VOID
@ -146,20 +137,14 @@ TCPFinEventHandler(void *arg, const err_t err)
PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg;
const NTSTATUS status = TCPTranslateError(err);
DbgPrint("[IP, TCPFinEventHandler] Called for Connection( 0x%x )-> SocketContext = pcb (0x%x)\n", Connection, Connection->SocketContext);
/* Only clear the pointer if the shutdown was caused by an error */
if (err != ERR_OK)
{
/* We're already closed by the error so we don't want to call lwip_close */
DbgPrint("[IP, TCPFinEventHandler] MAKING Connection( 0x%x )-> SocketContext = pcb (0x%x) NULL\n", Connection, Connection->SocketContext);
/* We're got closed by the error so remove the PCB pointer */
Connection->SocketContext = NULL;
}
FlushAllQueues(Connection, status);
DbgPrint("[IP, TCPFinEventHandler] Done\n");
}
VOID
@ -171,9 +156,7 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb)
PIRP Irp;
NTSTATUS Status;
KIRQL OldIrql;
DbgPrint("[IP, TCPAcceptEventHandler] Called\n");
ReferenceObject(Connection);
while ((Entry = ExInterlockedRemoveHeadList(&Connection->ListenRequest, &Connection->Lock)))
@ -194,16 +177,9 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb)
Bucket->Status = Status;
Bucket->Information = 0;
DbgPrint("[IP, TCPAcceptEventHandler] Completing accept event %x\n", Status);
if (Status == STATUS_SUCCESS)
{
DbgPrint("[IP, TCPAcceptEventHandler] newpcb->state = %s, listen_pcb->state = %s, newpcb = 0x%x\n",
tcp_state_str[newpcb->state],
tcp_state_str[((PTCP_PCB)Connection->SocketContext)->state],
newpcb);
LockObject(Bucket->AssociatedEndpoint, &OldIrql);
/* sanity assert...this should never be in anything else but a CLOSED state */
@ -217,13 +193,10 @@ TCPAcceptEventHandler(void *arg, PTCP_PCB newpcb)
LibTCPAccept(newpcb, (PTCP_PCB)Connection->SocketContext, Bucket->AssociatedEndpoint);
DbgPrint("[IP, TCPAcceptEventHandler] Trying to unlock Bucket->AssociatedEndpoint\n");
UnlockObject(Bucket->AssociatedEndpoint, OldIrql);
}
DereferenceObject(Bucket->AssociatedEndpoint);
DbgPrint("[IP, TCPAcceptEventHandler] Done!\n");
CompleteBucket(Connection, Bucket, FALSE);
}
@ -241,8 +214,6 @@ TCPSendEventHandler(void *arg, u16_t space)
NTSTATUS Status;
PMDL Mdl;
DbgPrint("[IP, TCPSendEventHandler] Called\n");
ReferenceObject(Connection);
while ((Entry = ExInterlockedRemoveHeadList(&Connection->SendRequest, &Connection->Lock)))
@ -262,8 +233,6 @@ TCPSendEventHandler(void *arg, u16_t space)
TI_DbgPrint(DEBUG_TCP,
("Writing %d bytes to %x\n", SendLen, SendBuffer));
DbgPrint("[IP, TCPSendEventHandler] Sending out &d bytes on pcb = 0x%x\n",
Connection->SocketContext);
TI_DbgPrint(DEBUG_TCP, ("Connection: %x\n", Connection));
TI_DbgPrint
@ -292,16 +261,12 @@ TCPSendEventHandler(void *arg, u16_t space)
Bucket->Status = Status;
Bucket->Information = (Bucket->Status == STATUS_SUCCESS) ? SendLen : 0;
DbgPrint("Completing send req %x\n", Status);
CompleteBucket(Connection, Bucket, FALSE);
}
}
DereferenceObject(Connection);
DbgPrint("[IP, TCPSendEventHandler] Leaving\n");
}
u32_t
@ -319,9 +284,7 @@ TCPRecvEventHandler(void *arg, struct pbuf *p)
ASSERT(p);
ReferenceObject(Connection);
DbgPrint("[IP, TCPRecvEventHandler] Called\n");
if ((Entry = ExInterlockedRemoveHeadList(&Connection->ReceiveRequest, &Connection->Lock)))
{
Bucket = CONTAINING_RECORD( Entry, TDI_BUCKET, Entry );
@ -345,9 +308,6 @@ TCPRecvEventHandler(void *arg, struct pbuf *p)
for (Received = 0; Received < RecvLen; Received += p->len, p = p->next)
{
DbgPrint("[IP, TCPRecvEventHandler] 0x%x: Copying %d bytes to 0x%x from 0x%x\n",
p, p->len, ((PUCHAR)RecvBuffer) + Received, p->payload);
RtlCopyMemory(RecvBuffer + Received, p->payload, p->len);
}
@ -360,8 +320,6 @@ TCPRecvEventHandler(void *arg, struct pbuf *p)
}
DereferenceObject(Connection);
DbgPrint("[IP, TCPRecvEventHandler] Leaving\n");
return Received;
}
@ -372,9 +330,7 @@ TCPConnectEventHandler(void *arg, err_t err)
PCONNECTION_ENDPOINT Connection = (PCONNECTION_ENDPOINT)arg;
PTDI_BUCKET Bucket;
PLIST_ENTRY Entry;
DbgPrint("[IP, TCPConnectEventHandler] Called\n");
ReferenceObject(Connection);
while ((Entry = ExInterlockedRemoveHeadList(&Connection->ConnectRequest, &Connection->Lock)))
@ -384,13 +340,9 @@ TCPConnectEventHandler(void *arg, err_t err)
Bucket->Status = TCPTranslateError(err);
Bucket->Information = 0;
DbgPrint("[IP, TCPConnectEventHandler] Completing connection request! (0x%x)\n", err);
CompleteBucket(Connection, Bucket, FALSE);
}
DbgPrint("[IP, TCPConnectEventHandler] Done\n");
DereferenceObject(Connection);
}

View file

@ -25,8 +25,6 @@ TCPSendDataCallback(struct netif *netif, struct pbuf *p, struct ip_addr *dest)
/* The caller frees the pbuf struct */
DbgPrint("[IP, TCPSendDataCallback] Sending data out on %c%c\n", netif->name[0], netif->name[1]);
if (((*(u8_t*)p->payload) & 0xF0) == 0x40)
{
Header = p->payload;
@ -39,21 +37,18 @@ TCPSendDataCallback(struct netif *netif, struct pbuf *p, struct ip_addr *dest)
}
else
{
DbgPrint("[IP, TCPSendDataCallback] FAIL EINVAL 1\n");
return EINVAL;
return ERR_IF;
}
if (!(NCE = RouteGetRouteToDestination(&RemoteAddress)))
{
DbgPrint("[IP, TCPSendDataCallback] FAIL EINVAL 2\n");
return EINVAL;
return ERR_RTE;
}
NdisStatus = AllocatePacketWithBuffer(&Packet.NdisPacket, NULL, p->tot_len);
if (NdisStatus != NDIS_STATUS_SUCCESS)
{
DbgPrint("[IP, TCPSendDataCallback] FAIL ENOBUFS\n");
return ENOBUFS;
return ERR_MEM;
}
GetDataPtr(Packet.NdisPacket, 0, (PCHAR*)&Packet.Header, &Packet.ContigSize);
@ -71,9 +66,8 @@ TCPSendDataCallback(struct netif *netif, struct pbuf *p, struct ip_addr *dest)
if (!NT_SUCCESS(IPSendDatagram(&Packet, NCE, TCPPacketSendComplete, NULL)))
{
DbgPrint("[IP, TCPSendDataCallback] FAIL EINVAL 3\n");
FreeNdisPacket(Packet.NdisPacket);
return EINVAL;
return ERR_IF;
}
return 0;

View file

@ -29,8 +29,6 @@ VOID ConnectionFree(PVOID Object)
KIRQL OldIrql;
TI_DbgPrint(DEBUG_TCP, ("Freeing TCP Endpoint\n"));
DbgPrint("CONNECTION ENDPOINT: Freeing 0x%x\n", Object);
TcpipAcquireSpinLock(&ConnectionEndpointListLock, &OldIrql);
RemoveEntryList(&Connection->ListEntry);
@ -85,9 +83,6 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Called: Connection %x, Family %d, Type %d, "
"Proto %d, sizeof(CONNECTION_ENDPOINT) = %d\n",
Connection, Family, Type, Proto, sizeof(CONNECTION_ENDPOINT)));
DbgPrint("[IP, TCPSocket] Called: Connection 0x%x, Family %d, Type %d, "
"Proto %d, sizeof(CONNECTION_ENDPOINT) = %d\n",
Connection, Family, Type, Proto, sizeof(CONNECTION_ENDPOINT));
Connection->SocketContext = LibTCPSocket(Connection);
if (Connection->SocketContext)
@ -95,12 +90,9 @@ NTSTATUS TCPSocket( PCONNECTION_ENDPOINT Connection,
else
Status = STATUS_INSUFFICIENT_RESOURCES;
DbgPrint("[IP, TCPSocket] Connection->SocketContext = 0x%x\n", Connection->SocketContext);
UnlockObject(Connection, OldIrql);
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSocket] Leaving. Status = 0x%x\n", Status));
DbgPrint("[IP, TCPSocket] Leaving. Status = 0x%x\n", Status);
return Status;
}
@ -112,8 +104,6 @@ NTSTATUS TCPClose( PCONNECTION_ENDPOINT Connection )
LockObject(Connection, &OldIrql);
DbgPrint("[IP, TCPClose] Called for Connection( 0x%x )->SocketConext( 0x%x )\n", Connection, Connection->SocketContext);
Socket = Connection->SocketContext;
/* We should not be associated to an address file at this point */
@ -124,13 +114,9 @@ NTSTATUS TCPClose( PCONNECTION_ENDPOINT Connection )
{
FlushAllQueues(Connection, STATUS_CANCELLED);
DbgPrint("[IP, TCPClose] Socket (pcb) = 0x%x\n", Socket);
LibTCPClose(Connection, FALSE);
}
DbgPrint("[IP, TCPClose] Leaving\n");
UnlockObject(Connection, OldIrql);
DereferenceObject(Connection);
@ -147,15 +133,11 @@ VOID TCPReceive(PIP_INTERFACE Interface, PIP_PACKET IPPacket)
* This is the low level interface for receiving TCP data
*/
{
DbgPrint("[IP, TCPReceive] Called. Got packet from network stack\n");
TI_DbgPrint(DEBUG_TCP,("Sending packet %d (%d) to lwIP\n",
IPPacket->TotalSize,
IPPacket->HeaderSize));
LibIPInsertPacket(Interface->TCPContext, IPPacket->Header, IPPacket->TotalSize);
DbgPrint("[IP, TCPReceive] Leaving\n");
}
NTSTATUS TCPStartup(VOID)
@ -217,7 +199,7 @@ NTSTATUS TCPTranslateError(const err_t err)
case ERR_MEM: Status = STATUS_INSUFFICIENT_RESOURCES; break; //-1
case ERR_BUF: Status = STATUS_BUFFER_TOO_SMALL; break; //-2
case ERR_TIMEOUT: Status = STATUS_TIMEOUT; break; // -3
case ERR_RTE: Status = STATUS_HOST_UNREACHABLE; break; //-4
case ERR_RTE: Status = STATUS_NETWORK_UNREACHABLE; break; //-4
case ERR_ABRT: Status = STATUS_LOCAL_DISCONNECT; break; //-5
case ERR_RST: Status = STATUS_REMOTE_DISCONNECT; break; //-6
case ERR_CLSD: Status = STATUS_FILE_CLOSED; break; //-7
@ -302,8 +284,6 @@ NTSTATUS TCPConnect
&bindaddr,
Connection->AddressFile->Port));
DbgPrint("LibTCPBind: 0x%x\n", Status);
if (NT_SUCCESS(Status))
{
/* Check if we had an unspecified port */
@ -340,8 +320,6 @@ NTSTATUS TCPConnect
Status = TCPTranslateError(LibTCPConnect(Connection,
&connaddr,
RemotePort));
DbgPrint("LibTCPConnect: 0x%x\n", Status);
}
}
@ -382,11 +360,8 @@ NTSTATUS TCPDisconnect
else
{
/* We already got closed by the other side so just return success */
DbgPrint("[IP, TCPDisconnect] Socket was alraedy clsoed on the other side\n");
Status = STATUS_SUCCESS;
}
DbgPrint("LibTCPShutdown: %x\n", Status);
UnlockObject(Connection, OldIrql);
@ -413,9 +388,6 @@ NTSTATUS TCPReceiveData
TI_DbgPrint(DEBUG_TCP,("[IP, TCPReceiveData] Called for %d bytes (on socket %x)\n",
ReceiveLength, Connection->SocketContext));
DbgPrint("[IP, TCPReceiveData] Called for %d bytes (on Connection->SocketContext = 0x%x)\n",
ReceiveLength, Connection->SocketContext);
NdisQueryBuffer(Buffer, &DataBuffer, &DataLen);
Status = LibTCPGetDataFromConnectionQueue(Connection, DataBuffer, DataLen, &Received);
@ -451,9 +423,6 @@ NTSTATUS TCPReceiveData
(*BytesReceived) = Received;
}
DbgPrint("[IP, TCPReceiveData] Leaving. Status = %s\n",
Status == STATUS_PENDING? "STATUS_PENDING" : "STATUS_SUCCESS");
return Status;
}
@ -478,15 +447,12 @@ NTSTATUS TCPSendData
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Connection = %x\n", Connection));
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Connection->SocketContext = %x\n",
Connection->SocketContext));
DbgPrint("[IP, TCPSendData] Called\n");
Status = TCPTranslateError(LibTCPSend(Connection,
BufferData,
SendLength,
FALSE));
DbgPrint("[IP, TCPSendData] LibTCPSend: 0x%x\n", Status);
TI_DbgPrint(DEBUG_TCP,("[IP, TCPSendData] Send: %x, %d\n", Status, SendLength));
/* Keep this request around ... there was no data yet */
@ -519,8 +485,6 @@ NTSTATUS TCPSendData
TI_DbgPrint(DEBUG_TCP, ("[IP, TCPSendData] Leaving. Status = %x\n", Status));
DbgPrint("[IP, TCPSendData] Leaving. Status = %x\n", Status);
return Status;
}
@ -578,8 +542,6 @@ NTSTATUS TCPGetSockAddress
AddressIP->Address[0].Address[0].in_addr = ipaddr.addr;
DbgPrint("LibTCPGetXXXName: 0x%x\n", Status);
return Status;
}

View file

@ -325,6 +325,9 @@ tcp_abandon(struct tcp_pcb *pcb, int reset)
#endif /* LWIP_CALLBACK_API */
void *errf_arg;
DbgPrint("tcp_abandon: called on pcb = 0x%x\n", pcb);
DbgPrint("tcp_abandon: pcb->state = %s\n", tcp_state_str[pcb->state]);
/* pcb->state LISTEN not allowed here */
LWIP_ASSERT("don't call tcp_abort/tcp_abandon for listen-pcbs",
pcb->state != LISTEN);
@ -917,6 +920,7 @@ tcp_slowtmr(void)
tcp_active_pcbs = pcb->next;
}
DbgPrint("tcp_slowtmr: removing pcb 0x%x\n", pcb);
TCP_EVENT_ERR(pcb->errf, pcb->callback_arg, ERR_ABRT);
if (pcb_reset) {
tcp_rst(pcb->snd_nxt, pcb->rcv_nxt, &pcb->local_ip, &pcb->remote_ip,
@ -1430,6 +1434,7 @@ tcp_pcb_purge(struct tcp_pcb *pcb)
void
tcp_pcb_remove(struct tcp_pcb **pcblist, struct tcp_pcb *pcb)
{
DbgPrint("tcp_pcb_remove: Removing pcb = 0x%x\n", pcb);
TCP_RMV(pcblist, pcb);
tcp_pcb_purge(pcb);

View file

@ -28,7 +28,6 @@ calloc(mem_size_t count, mem_size_t size)
void
free(void *mem)
{
//DbgPrint("ROSMEM: free 0x%x\n", mem);
ExFreePoolWithTag(mem, LWIP_TAG);
}

View file

@ -41,11 +41,10 @@ LibTCPEmptyQueue(PCONNECTION_ENDPOINT Connection)
while (!IsListEmpty(&Connection->PacketQueue))
{
DbgPrint("[lwIP, LibTCPEmptyQueue] Removed packet off queue++++\n");
Entry = RemoveHeadList(&Connection->PacketQueue);
qp = CONTAINING_RECORD(Entry, QUEUE_ENTRY, ListEntry);
/* We're in the tcpip thread here so this is safe */
pbuf_free(qp->p);
ExFreePoolWithTag(qp, LWIP_TAG);
@ -84,8 +83,6 @@ NTSTATUS LibTCPGetDataFromConnectionQueue(PCONNECTION_ENDPOINT Connection, PUCHA
if (!IsListEmpty(&Connection->PacketQueue))
{
DbgPrint("[lwIP, LibTCPGetDataFromConnectionQueue] Getting packet off the queue\n");
qp = LibTCPDequeuePacket(Connection);
p = qp->p;
@ -93,22 +90,18 @@ NTSTATUS LibTCPGetDataFromConnectionQueue(PCONNECTION_ENDPOINT Connection, PUCHA
for ((*Received) = 0; (*Received) < RecvLen; (*Received) += p->len, p = p->next)
{
DbgPrint("[lwIP, LibTCPGetDataFromConnectionQueue] 0x%x: Copying %d bytes to 0x%x from 0x%x\n",
p, p->len, ((PUCHAR)RecvBuffer) + (*Received), p->payload);
RtlCopyMemory(RecvBuffer + (*Received), p->payload, p->len);
}
// reenable this later
pbuf_free(qp->p);
/* Use this special pbuf free callback function because we're outside tcpip thread */
pbuf_free_callback(qp->p);
ExFreePoolWithTag(qp, LWIP_TAG);
Status = STATUS_SUCCESS;
}
else
{
DbgPrint("[lwIP, LibTCPGetPacketFromQueue] Queue is EMPTY\n");
Status = STATUS_PENDING;
}
@ -144,17 +137,10 @@ static
err_t
InternalSendEventHandler(void *arg, PTCP_PCB pcb, const u16_t space)
{
DbgPrint("[lwIP, InternalSendEventHandler] SendEvent (0x%x, 0x%x, %d)\n",
arg, pcb, (unsigned int)space);
ASSERT(pcb->sent != 0);
/* Make sure the socket didn't get closed */
if (!arg) return ERR_OK;
TCPSendEventHandler(arg, space);
DbgPrint("[lwIP, InternalSendEventHandler] Done\n");
return ERR_OK;
}
@ -165,27 +151,17 @@ InternalRecvEventHandler(void *arg, PTCP_PCB pcb, struct pbuf *p, const err_t er
{
u32_t len;
DbgPrint("[lwIP, InternalRecvEventHandler] RecvEvent (0x%x, pcb = 0x%x, pbuf = 0x%x, err = %d)\n",
arg, pcb, p, (unsigned int)err);
ASSERT(pcb->recv != NULL);
/* Make sure the socket didn't get closed */
if (!arg)
{
if (p)
pbuf_free(p);
DbgPrint("[lwIP, InternalRecvEventHandler] Done ERR_OK 0 - socket got closed on us\n");
return ERR_OK;
}
if (p)
{
DbgPrint("[lwIP, InternalRecvEventHandler] RECV - p:0x%x p->payload:0x%x p->len:%d p->tot_len:%d\n",
p, p->payload, p->len, p->tot_len);
len = TCPRecvEventHandler(arg, p);
if (len == p->tot_len)
{
@ -193,8 +169,6 @@ InternalRecvEventHandler(void *arg, PTCP_PCB pcb, struct pbuf *p, const err_t er
pbuf_free(p);
DbgPrint("[lwIP, InternalRecvEventHandler] Done ERR_OK 1\n");
return ERR_OK;
}
else if (len != 0)
@ -204,20 +178,16 @@ InternalRecvEventHandler(void *arg, PTCP_PCB pcb, struct pbuf *p, const err_t er
tcp_recved(pcb, len);
/* Possible memory leak of pbuf here? */
DbgPrint("[lwIP, InternalRecvEventHandler] Done ERR_OK 2\n");
return ERR_OK;
}
else
{
/* We want lwIP to store the pbuf on its queue for later */
DbgPrint("[lwIP, InternalRecvEventHandler] Done ERR_TIMEOUT queuing pbuf\n");
LibTCPEnqueuePacket((PCONNECTION_ENDPOINT)arg, p);
tcp_recved(pcb, p->tot_len);
return ERR_OK;//ERR_TIMEOUT;//
return ERR_OK;
}
}
else if (err == ERR_OK)
@ -228,8 +198,6 @@ InternalRecvEventHandler(void *arg, PTCP_PCB pcb, struct pbuf *p, const err_t er
*/
TCPFinEventHandler(arg, ERR_OK);
}
DbgPrint("[lwIP, InternalRecvEventHandler] Done ERR_OK 3\n");
return ERR_OK;
}
@ -238,15 +206,9 @@ static
err_t
InternalAcceptEventHandler(void *arg, PTCP_PCB newpcb, const err_t err)
{
DbgPrint("[lwIP, InternalAcceptEventHandler] AcceptEvent arg = 0x%x, newpcb = 0x%x, err = %d\n",
arg, newpcb, (unsigned int)err);
/* Make sure the socket didn't get closed */
if (!arg)
return ERR_ABRT;
DbgPrint("[lwIP, InternalAcceptEventHandler] newpcb->state = %s\n",
tcp_state_str[newpcb->state]);
TCPAcceptEventHandler(arg, newpcb);
@ -261,16 +223,11 @@ static
err_t
InternalConnectEventHandler(void *arg, PTCP_PCB pcb, const err_t err)
{
DbgPrint("[lwIP, InternalConnectEventHandler] ConnectEvent (0x%x, pcb = 0x%x, err = %d)\n",
arg, pcb, (unsigned int)err);
/* Make sure the socket didn't get closed */
if (!arg)
return ERR_OK;
TCPConnectEventHandler(arg, err);
DbgPrint("[lwIP, InternalConnectEventHandler] Done\n");
return ERR_OK;
}
@ -307,12 +264,8 @@ LibTCPSocketCallback(void *arg)
struct socket_callback_msg *msg = arg;
ASSERT(msg);
DbgPrint("[lwIP, LibTCPSocketCallback] Called\n");
msg->NewPcb = tcp_new();
DbgPrint("[lwIP, LibTCPSocketCallback] Assigned new pcb = 0x%x\n", msg->NewPcb);
if (msg->NewPcb)
{
@ -328,8 +281,6 @@ LibTCPSocket(void *arg)
{
struct socket_callback_msg *msg = ExAllocatePool(NonPagedPool, sizeof(struct socket_callback_msg));
struct tcp_pcb *ret;
DbgPrint("[lwIP, LibTCPSocket] Called\n");
if (msg)
{
@ -343,16 +294,10 @@ LibTCPSocket(void *arg)
else
ret = NULL;
DbgPrint("[lwIP, LibTCPSocket] Connection( 0x%x )->SocketContext = pcb( 0x%x )\n", arg, ret);
DbgPrint("[lwIP, LibTCPSocket] Done\n");
ExFreePool(msg);
return ret;
}
DbgPrint("[lwIP, LibTCPSocket] Done\n");
return NULL;
}
@ -379,10 +324,17 @@ LibTCPBindCallback(void *arg)
ASSERT(msg);
if (!msg->Connection->SocketContext)
{
msg->Error = ERR_CLSD;
goto done;
}
msg->Error = tcp_bind((PTCP_PCB)msg->Connection->SocketContext,
msg->IpAddress,
ntohs(msg->Port));
done:
KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE);
}
@ -392,11 +344,6 @@ LibTCPBind(PCONNECTION_ENDPOINT Connection, struct ip_addr *const ipaddr, const
struct bind_callback_msg *msg;
err_t ret;
if (!Connection->SocketContext)
return ERR_CLSD;
DbgPrint("[lwIP, LibTCPBind] Called\n");
msg = ExAllocatePool(NonPagedPool, sizeof(struct bind_callback_msg));
if (msg)
{
@ -412,10 +359,6 @@ LibTCPBind(PCONNECTION_ENDPOINT Connection, struct ip_addr *const ipaddr, const
else
ret = ERR_CLSD;
DbgPrint("[lwIP, LibTCPBind] pcb = 0x%x\n", Connection->SocketContext);
DbgPrint("[lwIP, LibTCPBind] Done\n");
ExFreePool(msg);
return ret;
@ -444,8 +387,12 @@ LibTCPListenCallback(void *arg)
struct listen_callback_msg *msg = arg;
ASSERT(msg);
DbgPrint("[lwIP, LibTCPListenCallback] Called\n");
if (!msg->Connection->SocketContext)
{
msg->NewPcb = NULL;
goto done;
}
msg->NewPcb = tcp_listen_with_backlog((PTCP_PCB)msg->Connection->SocketContext, msg->Backlog);
@ -453,9 +400,8 @@ LibTCPListenCallback(void *arg)
{
tcp_accept(msg->NewPcb, InternalAcceptEventHandler);
}
DbgPrint("[lwIP, LibTCPListenCallback] Done\n");
done:
KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE);
}
@ -464,11 +410,6 @@ LibTCPListen(PCONNECTION_ENDPOINT Connection, const u8_t backlog)
{
struct listen_callback_msg *msg;
PTCP_PCB ret;
DbgPrint("[lwIP, LibTCPListen] Called on pcb = 0x%x\n", Connection->SocketContext);
if (!Connection->SocketContext)
return NULL;
msg = ExAllocatePool(NonPagedPool, sizeof(struct listen_callback_msg));
if (msg)
@ -484,11 +425,6 @@ LibTCPListen(PCONNECTION_ENDPOINT Connection, const u8_t backlog)
else
ret = NULL;
DbgPrint("[lwIP, LibTCPListen] pcb = 0x%x, newpcb = 0x%x, sizeof(pcb) = %d \n",
Connection->SocketContext, ret, sizeof(struct tcp_pcb));
DbgPrint("[lwIP, LibTCPListen] Done\n");
ExFreePool(msg);
return ret;
@ -519,6 +455,12 @@ LibTCPSendCallback(void *arg)
ASSERT(msg);
if (!msg->Connection->SocketContext)
{
msg->Error = ERR_CLSD;
goto done;
}
if (tcp_sndbuf((PTCP_PCB)msg->Connection->SocketContext) < msg->DataLength)
{
msg->Error = ERR_INPROGRESS;
@ -533,6 +475,7 @@ LibTCPSendCallback(void *arg)
tcp_output((PTCP_PCB)msg->Connection->SocketContext);
}
done:
KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE);
}
@ -540,54 +483,29 @@ err_t
LibTCPSend(PCONNECTION_ENDPOINT Connection, void *const dataptr, const u16_t len, const int safe)
{
err_t ret;
struct send_callback_msg *msg;
if (!Connection->SocketContext)
return ERR_CLSD;
/*
If we're being called from a handler it means we're in the conetxt of teh tcpip
main thread. Therefore we don't have to queue our request via a callback and we
can execute immediately.
*/
if (safe)
msg = ExAllocatePool(NonPagedPool, sizeof(struct send_callback_msg));
if (msg)
{
if (tcp_sndbuf((PTCP_PCB)Connection->SocketContext) < len)
{
ret = ERR_INPROGRESS;
}
else
{
ret = tcp_write((PTCP_PCB)Connection->SocketContext, dataptr, len, TCP_WRITE_FLAG_COPY);
tcp_output((PTCP_PCB)Connection->SocketContext);
}
return ret;
}
else
{
struct send_callback_msg *msg;
msg = ExAllocatePool(NonPagedPool, sizeof(struct send_callback_msg));
if (msg)
{
KeInitializeEvent(&msg->Event, NotificationEvent, FALSE);
msg->Connection = Connection;
msg->Data = dataptr;
msg->DataLength = len;
KeInitializeEvent(&msg->Event, NotificationEvent, FALSE);
msg->Connection = Connection;
msg->Data = dataptr;
msg->DataLength = len;
if (safe)
LibTCPSendCallback(msg);
else
tcpip_callback_with_block(LibTCPSendCallback, msg, 1);
if (WaitForEventSafely(&msg->Event))
ret = msg->Error;
else
ret = ERR_CLSD;
if (WaitForEventSafely(&msg->Event))
ret = msg->Error;
else
ret = ERR_CLSD;
DbgPrint("[lwIP, LibTCPSend] pcb = 0x%x\n", Connection->SocketContext);
ExFreePool(msg);
ExFreePool(msg);
return ret;
}
return ret;
}
return ERR_MEM;
@ -612,11 +530,15 @@ void
LibTCPConnectCallback(void *arg)
{
struct connect_callback_msg *msg = arg;
DbgPrint("[lwIP, LibTCPConnectCallback] Called\n");
ASSERT(arg);
if (!msg->Connection->SocketContext)
{
msg->Error = ERR_CLSD;
goto done;
}
tcp_recv((PTCP_PCB)msg->Connection->SocketContext, InternalRecvEventHandler);
tcp_sent((PTCP_PCB)msg->Connection->SocketContext, InternalSendEventHandler);
@ -626,9 +548,8 @@ LibTCPConnectCallback(void *arg)
msg->Error = Error == ERR_OK ? ERR_INPROGRESS : Error;
done:
KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE);
DbgPrint("[lwIP, LibTCPConnectCallback] Done\n");
}
err_t
@ -636,11 +557,6 @@ LibTCPConnect(PCONNECTION_ENDPOINT Connection, struct ip_addr *const ipaddr, con
{
struct connect_callback_msg *msg;
err_t ret;
DbgPrint("[lwIP, LibTCPConnect] Called\n");
if (!Connection->SocketContext)
return ERR_CLSD;
msg = ExAllocatePool(NonPagedPool, sizeof(struct connect_callback_msg));
if (msg)
@ -660,10 +576,6 @@ LibTCPConnect(PCONNECTION_ENDPOINT Connection, struct ip_addr *const ipaddr, con
ret = ERR_CLSD;
ExFreePool(msg);
DbgPrint("[lwIP, LibTCPConnect] pcb = 0x%x\n", Connection->SocketContext);
DbgPrint("[lwIP, LibTCPConnect] Done\n");
return ret;
}
@ -690,6 +602,12 @@ void
LibTCPShutdownCallback(void *arg)
{
struct shutdown_callback_msg *msg = arg;
if (!msg->Connection->SocketContext)
{
msg->Error = ERR_CLSD;
goto done;
}
/*
We check here if the pcb is in state ESTABLISHED or SYN_RECV because otherwise
@ -706,6 +624,7 @@ LibTCPShutdownCallback(void *arg)
else
msg->Error = ERR_OK;
done:
KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE);
}
@ -714,19 +633,7 @@ LibTCPShutdown(PCONNECTION_ENDPOINT Connection, const int shut_rx, const int shu
{
struct shutdown_callback_msg *msg;
err_t ret;
DbgPrint("[lwIP, LibTCPShutdown] Called on pcb = 0x%x, rx = %d, tx = %d\n",
Connection->SocketContext, shut_rx, shut_tx);
if (!Connection->SocketContext)
{
DbgPrint("[lwIP, LibTCPShutdown] Done... NO pcb\n");
return ERR_CLSD;
}
DbgPrint("[lwIP, LibTCPShutdown] pcb->state = %s\n",
tcp_state_str[((PTCP_PCB)Connection->SocketContext)->state]);
msg = ExAllocatePool(NonPagedPool, sizeof(struct shutdown_callback_msg));
if (msg)
{
@ -745,8 +652,6 @@ LibTCPShutdown(PCONNECTION_ENDPOINT Connection, const int shut_rx, const int shu
ExFreePool(msg);
DbgPrint("[lwIP, LibTCPShutdown] Done\n");
return ret;
}
@ -765,57 +670,31 @@ struct close_callback_msg
err_t Error;
};
static
void
CloseCallbacks(struct tcp_pcb *pcb)
{
tcp_arg(pcb, NULL);
/*
if this pcb is not in LISTEN state then it has
valid recv, send and err callbacks to cancel
*/
if (pcb->state != LISTEN)
{
tcp_recv(pcb, NULL);
tcp_sent(pcb, NULL);
tcp_err(pcb, NULL);
}
tcp_accept(pcb, NULL);
}
static
void
LibTCPCloseCallback(void *arg)
{
struct close_callback_msg *msg = arg;
DbgPrint("[lwIP, LibTCPCloseCallback] pcb = 0x%x\n", (PTCP_PCB)msg->Connection->SocketContext);
if (!msg->Connection->SocketContext)
{
DbgPrint("[lwIP, LibTCPCloseCallback] NULL pcb...bail, bail!!!\n");
msg->Error = ERR_OK;
return;
goto done;
}
CloseCallbacks((PTCP_PCB)msg->Connection->SocketContext);
LibTCPEmptyQueue(msg->Connection);
if (((PTCP_PCB)msg->Connection->SocketContext)->state == LISTEN)
{
DbgPrint("[lwIP, LibTCPCloseCallback] Closing a listener\n");
msg->Error = tcp_close((PTCP_PCB)msg->Connection->SocketContext);
}
else
{
DbgPrint("[lwIP, LibTCPCloseCallback] Aborting a connection\n");
tcp_abort((PTCP_PCB)msg->Connection->SocketContext);
msg->Error = ERR_OK;
}
done:
KeSetEvent(&msg->Event, IO_NO_INCREMENT, FALSE);
}
@ -823,79 +702,36 @@ err_t
LibTCPClose(PCONNECTION_ENDPOINT Connection, const int safe)
{
err_t ret;
DbgPrint("[lwIP, LibTCPClose] Called on pcb = 0x%x\n", Connection->SocketContext);
struct close_callback_msg *msg;
if (!Connection->SocketContext)
msg = ExAllocatePool(NonPagedPool, sizeof(struct close_callback_msg));
if (msg)
{
DbgPrint("[lwIP, LibTCPClose] Done... NO pcb\n");
return ERR_CLSD;
}
DbgPrint("[lwIP, LibTCPClose] pcb->state = %s\n",
tcp_state_str[((PTCP_PCB)Connection->SocketContext)->state]);
/*
If we're being called from a handler it means we're in the conetxt of teh tcpip
main thread. Therefore we don't have to queue our request via a callback and we
can execute immediately.
*/
if (safe)
{
CloseCallbacks((PTCP_PCB)Connection->SocketContext);
KeInitializeEvent(&msg->Event, NotificationEvent, FALSE);
LibTCPEmptyQueue(Connection);
if ( ((PTCP_PCB)Connection->SocketContext)->state == LISTEN )
{
DbgPrint("[lwIP, LibTCPClose] Closing a listener\n");
ret = tcp_close((PTCP_PCB)Connection->SocketContext);
}
msg->Connection = Connection;
if (safe)
LibTCPCloseCallback(msg);
else
{
DbgPrint("[lwIP, LibTCPClose] Aborting a connection\n");
tcp_abort((PTCP_PCB)Connection->SocketContext);
ret = ERR_OK;
}
return ret;
}
else
{
struct close_callback_msg *msg;
msg = ExAllocatePool(NonPagedPool, sizeof(struct close_callback_msg));
if (msg)
{
KeInitializeEvent(&msg->Event, NotificationEvent, FALSE);
msg->Connection = Connection;
tcpip_callback_with_block(LibTCPCloseCallback, msg, 1);
if (WaitForEventSafely(&msg->Event))
ret = msg->Error;
else
ret = ERR_CLSD;
if (WaitForEventSafely(&msg->Event))
ret = msg->Error;
else
ret = ERR_CLSD;
ExFreePool(msg);
DbgPrint("[lwIP, LibTCPClose] Done\n");
ExFreePool(msg);
return ret;
}
return ret;
}
DbgPrint("[lwIP, LibTCPClose] Failed to allocate memory\n");
return ERR_MEM;
}
void
LibTCPAccept(PTCP_PCB pcb, struct tcp_pcb *listen_pcb, void *arg)
{
DbgPrint("[lwIP, LibTCPAccept] Called. (pcb, arg) = (0x%x, 0x%x)\n", pcb, arg);
ASSERT(arg);
tcp_arg(pcb, NULL);
@ -905,40 +741,28 @@ LibTCPAccept(PTCP_PCB pcb, struct tcp_pcb *listen_pcb, void *arg)
tcp_arg(pcb, arg);
tcp_accepted(listen_pcb);
DbgPrint("[lwIP, LibTCPAccept] Done\n");
}
err_t
LibTCPGetHostName(PTCP_PCB pcb, struct ip_addr *const ipaddr, u16_t *const port)
{
DbgPrint("[lwIP, LibTCPGetHostName] Called. pcb = (0x%x)\n", pcb);
if (!pcb)
return ERR_CLSD;
*ipaddr = pcb->local_ip;
*port = pcb->local_port;
DbgPrint("[lwIP, LibTCPGetHostName] Got host port: %d\n", *port);
DbgPrint("[lwIP, LibTCPGetHostName] Done\n");
return ERR_OK;
}
err_t
LibTCPGetPeerName(PTCP_PCB pcb, struct ip_addr * const ipaddr, u16_t * const port)
{
DbgPrint("[lwIP, LibTCPGetPeerName] pcb = (0x%x)\n", pcb);
{
if (!pcb)
return ERR_CLSD;
*ipaddr = pcb->remote_ip;
*port = pcb->remote_port;
DbgPrint("[lwIP, LibTCPGetPeerName] Got remote port: %d\n", *port);
return ERR_OK;
}

View file

@ -95,10 +95,6 @@ sys_arch_sem_wait(sys_sem_t* sem, u32_t timeout)
KeQuerySystemTime(&PreWaitTime);
// FIXME: This is a hack to increase the throughput. Once this is done
// the right way it should definately be removed.
//timeout = 5;
Status = KeWaitForMultipleObjects(2,
WaitObjects,
WaitAny,
@ -107,17 +103,12 @@ sys_arch_sem_wait(sys_sem_t* sem, u32_t timeout)
FALSE,
timeout != 0 ? &LargeTimeout : NULL,
NULL);
//DbgPrint("[+[+[+[ sys_arch_sem_wait ]+]+]+] timeout = %d\n", timeout);
if (Status == STATUS_WAIT_0)
{
KeQuerySystemTime(&PostWaitTime);
TimeDiff = PostWaitTime.QuadPart - PreWaitTime.QuadPart;
TimeDiff /= 10000;
//DbgPrint("[+[+[+[ sys_arch_sem_wait ]+]+]+] TimeDiff = %llu\n", TimeDiff);
return TimeDiff;
}
else if (Status == STATUS_WAIT_1)
@ -130,8 +121,6 @@ sys_arch_sem_wait(sys_sem_t* sem, u32_t timeout)
return 0;
}
//DbgPrint("[+[+[+[ sys_arch_sem_wait ]+]+]+] SYS_ARCH_TIMEOUT\n");
return SYS_ARCH_TIMEOUT;
}
@ -196,9 +185,6 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
PLIST_ENTRY Entry;
KIRQL OldIrql;
PVOID WaitObjects[] = {&mbox->Event, &TerminationEvent};
//timeout = 0;
//DbgPrint("[[[[[ sys_arch_mbox_fetch ]]]]] %d\n", timeout);
LargeTimeout.QuadPart = Int32x32To64(timeout, -10000);
@ -213,8 +199,6 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
timeout != 0 ? &LargeTimeout : NULL,
NULL);
//DbgPrint("[ [ [ [ sys_arch_mbox_fetch ] ] ] ] timeout = %d\n", timeout);
if (Status == STATUS_WAIT_0)
{
KeAcquireSpinLock(&mbox->Lock, &OldIrql);
@ -234,8 +218,6 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
KeQuerySystemTime(&PostWaitTime);
TimeDiff = PostWaitTime.QuadPart - PreWaitTime.QuadPart;
TimeDiff /= 10000;
//DbgPrint("[ [ [ [ sys_arch_mbox_fetch ] ] ] ] TimeDiff = %llu\n", TimeDiff);
return TimeDiff;
}
@ -249,8 +231,6 @@ sys_arch_mbox_fetch(sys_mbox_t *mbox, void **msg, u32_t timeout)
return 0;
}
//DbgPrint("[ [ [ [ sys_arch_mbox_fetch ] ] ] ] SYS_ARCH_TIMEOUT\n");
return SYS_ARCH_TIMEOUT;
}
@ -276,7 +256,7 @@ VOID
NTAPI
LwipThreadMain(PVOID Context)
{
thread_t Container = Context;
thread_t Container = (thread_t)Context;
KIRQL OldIrql;
ExInterlockedInsertHeadList(&ThreadListHead, &Container->ListEntry, &ThreadListLock);
@ -324,9 +304,8 @@ sys_thread_new(const char *name, lwip_thread_fn thread, void *arg, int stacksize
void
sys_init(void)
{
{
KeInitializeSpinLock(&ThreadListLock);
InitializeListHead(&ThreadListHead);
KeQuerySystemTime(&StartTime);