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

View file

@ -148,6 +148,7 @@ int OskitTCPRecv( void *connection,
OSK_UINT Len,
OSK_UINT *OutLen,
OSK_UINT Flags ) {
struct socket *so = connection;
struct uio uio = { 0 };
struct iovec iov = { 0 };
int error = 0;
@ -155,9 +156,12 @@ int OskitTCPRecv( void *connection,
if (!connection)
return OSK_ESHUTDOWN;
if (so->so_state & SS_CANTRCVMORE)
return OSK_ESHUTDOWN;
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_DONTWAIT ) tcp_flags |= MSG_DONTWAIT;
@ -290,12 +294,16 @@ int OskitTCPClose( void *socket ) {
int OskitTCPSend( void *socket, OSK_PCHAR Data, OSK_UINT Len,
OSK_UINT *OutLen, OSK_UINT flags ) {
struct socket *so = socket;
int error;
struct uio uio;
struct iovec iov;
if (!socket)
return OSK_ESHUTDOWN;
if (so->so_state & SS_CANTSENDMORE)
return OSK_ESHUTDOWN;
iov.iov_len = Len;
iov.iov_base = (char *)Data;

View file

@ -31,11 +31,13 @@ void wakeup( struct socket *so, void *token ) {
OS_DbgPrint(OSK_MID_TRACE,("Socket accepting q\n"));
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"));
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"));
flags |= SEL_WRITE;
}
@ -51,7 +53,7 @@ void wakeup( struct socket *so, void *token ) {
if( OtcpEvent.SocketState )
OtcpEvent.SocketState( OtcpEvent.ClientData,
so,
so ? so->so_connection : 0,
so->so_connection,
flags );
if( OtcpEvent.Wakeup )

View file

@ -826,7 +826,13 @@ soshutdown(so, how)
{
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++;
#endif
if (how & FREAD)
sorflush(so);
if (how & FWRITE)