- Don't attempt to service a request if the only flag specified was SEL_FIN
- Handle TDI_DISCONNECT_RELEASE properly
[OSKITTCP]
- Verify that the socket is in a legal state to do a send or receive
- Don't indicate send and receive events when the socket is not connected or has been been closed in that particular direction
- Add a small hack to soshutdown so shutdown in the send direction works correctly (ie. doesn't shutdown receive)
- Fixes the hangs in ws2_32_apitest ioctlsocket and ws2_32_apitest recv

svn path=/trunk/; revision=52405
This commit is contained in:
Cameron Gutman 2011-06-21 16:23:27 +00:00
parent d5e9cb0dd8
commit 85b52ced7c
4 changed files with 58 additions and 21 deletions

View file

@ -69,10 +69,17 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
TI_DbgPrint(DEBUG_TCP,("Getting the socket\n")); TI_DbgPrint(DEBUG_TCP,("Getting the socket\n"));
Status = TCPServiceListeningSocket if (Connection->SignalState & SEL_ACCEPT)
( Connection->AddressFile->Listener, {
Status = TCPServiceListeningSocket(Connection->AddressFile->Listener,
Bucket->AssociatedEndpoint, Bucket->AssociatedEndpoint,
(PTDI_REQUEST_KERNEL)&IrpSp->Parameters ); (PTDI_REQUEST_KERNEL)&IrpSp->Parameters);
}
else
{
/* We got here because of a SEL_FIN event */
Status = STATUS_CANCELLED;
}
TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n")); TI_DbgPrint(DEBUG_TCP,("Socket: Status: %x\n"));
@ -121,12 +128,19 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
Connection->SocketContext)); Connection->SocketContext));
TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer)); TI_DbgPrint(DEBUG_TCP, ("RecvBuffer: %x\n", RecvBuffer));
Status = TCPTranslateError if (Connection->SignalState & SEL_READ)
( OskitTCPRecv( Connection->SocketContext, {
Status = TCPTranslateError(OskitTCPRecv(Connection->SocketContext,
RecvBuffer, RecvBuffer,
RecvLen, RecvLen,
&Received, &Received,
0 ) ); 0));
}
else
{
/* We got here because of a SEL_FIN event */
Status = STATUS_CANCELLED;
}
TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received)); TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Received));
@ -175,12 +189,19 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
("Connection->SocketContext: %x\n", ("Connection->SocketContext: %x\n",
Connection->SocketContext)); Connection->SocketContext));
Status = TCPTranslateError if (Connection->SignalState & SEL_WRITE)
( OskitTCPSend( Connection->SocketContext, {
Status = TCPTranslateError(OskitTCPSend(Connection->SocketContext,
SendBuffer, SendBuffer,
SendLen, SendLen,
&Sent, &Sent,
0 ) ); 0));
}
else
{
/* We got here because of a SEL_FIN event */
Status = STATUS_CANCELLED;
}
TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent)); TI_DbgPrint(DEBUG_TCP,("TCP Bytes: %d\n", Sent));
@ -648,7 +669,7 @@ NTSTATUS TCPDisconnect
LockObject(Connection, &OldIrql); LockObject(Connection, &OldIrql);
if (Flags & TDI_DISCONNECT_RELEASE) if (Flags & TDI_DISCONNECT_RELEASE)
Status = TCPTranslateError(OskitTCPDisconnect(Connection->SocketContext)); Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE));
if ((Flags & TDI_DISCONNECT_ABORT) || !Flags) if ((Flags & TDI_DISCONNECT_ABORT) || !Flags)
Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD)); Status = TCPTranslateError(OskitTCPShutdown(Connection->SocketContext, FWRITE | FREAD));

View file

@ -148,6 +148,7 @@ int OskitTCPRecv( void *connection,
OSK_UINT Len, OSK_UINT Len,
OSK_UINT *OutLen, OSK_UINT *OutLen,
OSK_UINT Flags ) { OSK_UINT Flags ) {
struct socket *so = connection;
struct uio uio = { 0 }; struct uio uio = { 0 };
struct iovec iov = { 0 }; struct iovec iov = { 0 };
int error = 0; int error = 0;
@ -156,8 +157,11 @@ int OskitTCPRecv( void *connection,
if (!connection) if (!connection)
return OSK_ESHUTDOWN; return OSK_ESHUTDOWN;
if (so->so_state & SS_CANTRCVMORE)
return OSK_ESHUTDOWN;
OS_DbgPrint(OSK_MID_TRACE, OS_DbgPrint(OSK_MID_TRACE,
("so->so_state %x\n", ((struct socket *)connection)->so_state)); ("so->so_state %x\n", so->so_state));
if( Flags & OSK_MSG_OOB ) tcp_flags |= MSG_OOB; if( Flags & OSK_MSG_OOB ) tcp_flags |= MSG_OOB;
if( Flags & OSK_MSG_DONTWAIT ) tcp_flags |= MSG_DONTWAIT; if( Flags & OSK_MSG_DONTWAIT ) tcp_flags |= MSG_DONTWAIT;
@ -290,6 +294,7 @@ int OskitTCPClose( void *socket ) {
int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len, int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
OSK_UINT *OutLen, OSK_UINT flags ) { OSK_UINT *OutLen, OSK_UINT flags ) {
struct socket *so = socket;
int error; int error;
struct uio uio; struct uio uio;
struct iovec iov; struct iovec iov;
@ -297,6 +302,9 @@ int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
if (!socket) if (!socket)
return OSK_ESHUTDOWN; return OSK_ESHUTDOWN;
if (so->so_state & SS_CANTSENDMORE)
return OSK_ESHUTDOWN;
iov.iov_len = Len; iov.iov_len = Len;
iov.iov_base = (char *)Data; iov.iov_base = (char *)Data;
uio.uio_iov = &iov; uio.uio_iov = &iov;

View file

@ -31,11 +31,13 @@ void wakeup( struct socket *so, void *token ) {
OS_DbgPrint(OSK_MID_TRACE,("Socket accepting q\n")); OS_DbgPrint(OSK_MID_TRACE,("Socket accepting q\n"));
flags |= SEL_ACCEPT; flags |= SEL_ACCEPT;
} }
if( so->so_rcv.sb_cc > 0 ) { if( so->so_rcv.sb_cc > 0 && !(so->so_state & SS_CANTRCVMORE) &&
(so->so_state & SS_ISCONNECTED) ) {
OS_DbgPrint(OSK_MID_TRACE,("Socket readable\n")); OS_DbgPrint(OSK_MID_TRACE,("Socket readable\n"));
flags |= SEL_READ; flags |= SEL_READ;
} }
if( 0 < sbspace(&so->so_snd) ) { if( 0 < sbspace(&so->so_snd) && !(so->so_state & SS_CANTSENDMORE) &&
(so->so_state & SS_ISCONNECTED) ) {
OS_DbgPrint(OSK_MID_TRACE,("Socket writeable\n")); OS_DbgPrint(OSK_MID_TRACE,("Socket writeable\n"));
flags |= SEL_WRITE; flags |= SEL_WRITE;
} }
@ -51,7 +53,7 @@ void wakeup( struct socket *so, void *token ) {
if( OtcpEvent.SocketState ) if( OtcpEvent.SocketState )
OtcpEvent.SocketState( OtcpEvent.ClientData, OtcpEvent.SocketState( OtcpEvent.ClientData,
so, so,
so ? so->so_connection : 0, so->so_connection,
flags ); flags );
if( OtcpEvent.Wakeup ) if( OtcpEvent.Wakeup )

View file

@ -826,7 +826,13 @@ soshutdown(so, how)
{ {
register struct protosw *pr = so->so_proto; register struct protosw *pr = so->so_proto;
#ifndef __REACTOS__
/* Reads are always killed whether we want
* them stopped or not. We don't want this
* happening on ROS so this code is commented out
*/
how++; how++;
#endif
if (how & FREAD) if (how & FREAD)
sorflush(so); sorflush(so);
if (how & FWRITE) if (how & FWRITE)