mirror of
https://github.com/reactos/reactos.git
synced 2025-08-02 13:37:12 +00:00
[OSKITTCP]
- Prevent multiple wakeups for the same event which caused nasty problems for the SEL_FIN event because we dereferenced our connection context 3 times which not only caused the connection endpoint to be freed while holding its spin lock but made the reference count negative [TCPIP] - Disassociate the address file from the connection endpoint before dereferencing/closing it to avoid a double dereference of the address file (not as harmful in this case as in the connection endpoint case) [IP] - Dereference the connection endpoint again if it was associated with an address file as the connection endpoint to fix a reference leak svn path=/trunk/; revision=48624
This commit is contained in:
parent
1b2ab4ce31
commit
0553d5160c
3 changed files with 36 additions and 6 deletions
|
@ -379,9 +379,15 @@ NTSTATUS FileCloseAddress(
|
|||
LockObject(AddrFile, &OldIrql);
|
||||
/* We have to close this connection because we started it */
|
||||
if( AddrFile->Listener )
|
||||
{
|
||||
AddrFile->Listener->AddressFile = NULL;
|
||||
TCPClose( AddrFile->Listener );
|
||||
}
|
||||
if( AddrFile->Connection )
|
||||
{
|
||||
AddrFile->Connection->AddressFile = NULL;
|
||||
DereferenceObject( AddrFile->Connection );
|
||||
}
|
||||
UnlockObject(AddrFile, OldIrql);
|
||||
|
||||
DereferenceObject(AddrFile);
|
||||
|
|
|
@ -234,7 +234,10 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
|
|||
|
||||
/* If the socket is dead, remove the reference we added for oskit */
|
||||
if (Connection->SignalState & SEL_FIN)
|
||||
{
|
||||
Connection->SocketContext = NULL;
|
||||
DereferenceObject(Connection);
|
||||
}
|
||||
}
|
||||
|
||||
VOID ConnectionFree(PVOID Object) {
|
||||
|
@ -663,17 +666,15 @@ NTSTATUS TCPClose
|
|||
KIRQL OldIrql;
|
||||
NTSTATUS Status;
|
||||
PVOID Socket;
|
||||
PADDRESS_FILE AddressFile = NULL;
|
||||
PCONNECTION_ENDPOINT AddressConnection = NULL;
|
||||
|
||||
/* We don't rely on SocketContext == NULL for socket
|
||||
* closure anymore but we still need it to determine
|
||||
* if we caused the closure
|
||||
*/
|
||||
LockObject(Connection, &OldIrql);
|
||||
Socket = Connection->SocketContext;
|
||||
Connection->SocketContext = NULL;
|
||||
|
||||
/* Don't try to close again if the other side closed us already */
|
||||
if (!(Connection->SignalState & SEL_FIN))
|
||||
if (Socket)
|
||||
{
|
||||
/* We need to close here otherwise oskit will never indicate
|
||||
* SEL_FIN and we will never fully close the connection */
|
||||
|
@ -693,11 +694,26 @@ NTSTATUS TCPClose
|
|||
}
|
||||
|
||||
if (Connection->AddressFile)
|
||||
DereferenceObject(Connection->AddressFile);
|
||||
{
|
||||
LockObjectAtDpcLevel(Connection->AddressFile);
|
||||
if (Connection->AddressFile->Connection == Connection)
|
||||
{
|
||||
AddressConnection = Connection->AddressFile->Connection;
|
||||
Connection->AddressFile->Connection = NULL;
|
||||
}
|
||||
UnlockObjectFromDpcLevel(Connection->AddressFile);
|
||||
|
||||
AddressFile = Connection->AddressFile;
|
||||
Connection->AddressFile = NULL;
|
||||
}
|
||||
|
||||
UnlockObject(Connection, OldIrql);
|
||||
|
||||
DereferenceObject(Connection);
|
||||
if (AddressConnection)
|
||||
DereferenceObject(AddressConnection);
|
||||
if (AddressFile)
|
||||
DereferenceObject(AddressFile);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
|
|
@ -118,8 +118,10 @@ soisconnected(so)
|
|||
wakeup(so, (caddr_t)&head->so_timeo);
|
||||
} else {
|
||||
wakeup(so, (caddr_t)&so->so_timeo);
|
||||
#ifndef __REACTOS__
|
||||
sorwakeup(so);
|
||||
sowwakeup(so);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,8 +133,10 @@ soisdisconnecting(so)
|
|||
so->so_state &= ~SS_ISCONNECTING;
|
||||
so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
|
||||
wakeup(so, (caddr_t)&so->so_timeo);
|
||||
#ifndef __REACTOS__
|
||||
sowwakeup(so);
|
||||
sorwakeup(so);
|
||||
#endif
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -144,8 +148,10 @@ soisdisconnected(so)
|
|||
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
|
||||
wakeup(so, (caddr_t)&so->so_timeo);
|
||||
#ifndef __REACTOS__
|
||||
sowwakeup(so);
|
||||
sorwakeup(so);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -192,7 +198,9 @@ sonewconn1(head, connstatus)
|
|||
return ((struct socket *)0);
|
||||
}
|
||||
if (connstatus) {
|
||||
#ifndef __REACTOS__
|
||||
sorwakeup(head);
|
||||
#endif
|
||||
wakeup(head, (caddr_t)&head->so_timeo);
|
||||
so->so_state |= connstatus;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue