mirror of
https://github.com/reactos/reactos.git
synced 2025-08-04 03:46:38 +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);
|
LockObject(AddrFile, &OldIrql);
|
||||||
/* We have to close this connection because we started it */
|
/* We have to close this connection because we started it */
|
||||||
if( AddrFile->Listener )
|
if( AddrFile->Listener )
|
||||||
|
{
|
||||||
|
AddrFile->Listener->AddressFile = NULL;
|
||||||
TCPClose( AddrFile->Listener );
|
TCPClose( AddrFile->Listener );
|
||||||
|
}
|
||||||
if( AddrFile->Connection )
|
if( AddrFile->Connection )
|
||||||
|
{
|
||||||
|
AddrFile->Connection->AddressFile = NULL;
|
||||||
DereferenceObject( AddrFile->Connection );
|
DereferenceObject( AddrFile->Connection );
|
||||||
|
}
|
||||||
UnlockObject(AddrFile, OldIrql);
|
UnlockObject(AddrFile, OldIrql);
|
||||||
|
|
||||||
DereferenceObject(AddrFile);
|
DereferenceObject(AddrFile);
|
||||||
|
|
|
@ -234,7 +234,10 @@ VOID HandleSignalledConnection(PCONNECTION_ENDPOINT Connection)
|
||||||
|
|
||||||
/* If the socket is dead, remove the reference we added for oskit */
|
/* If the socket is dead, remove the reference we added for oskit */
|
||||||
if (Connection->SignalState & SEL_FIN)
|
if (Connection->SignalState & SEL_FIN)
|
||||||
|
{
|
||||||
|
Connection->SocketContext = NULL;
|
||||||
DereferenceObject(Connection);
|
DereferenceObject(Connection);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VOID ConnectionFree(PVOID Object) {
|
VOID ConnectionFree(PVOID Object) {
|
||||||
|
@ -663,17 +666,15 @@ NTSTATUS TCPClose
|
||||||
KIRQL OldIrql;
|
KIRQL OldIrql;
|
||||||
NTSTATUS Status;
|
NTSTATUS Status;
|
||||||
PVOID Socket;
|
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);
|
LockObject(Connection, &OldIrql);
|
||||||
Socket = Connection->SocketContext;
|
Socket = Connection->SocketContext;
|
||||||
Connection->SocketContext = NULL;
|
Connection->SocketContext = NULL;
|
||||||
|
|
||||||
/* Don't try to close again if the other side closed us already */
|
/* 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
|
/* We need to close here otherwise oskit will never indicate
|
||||||
* SEL_FIN and we will never fully close the connection */
|
* SEL_FIN and we will never fully close the connection */
|
||||||
|
@ -693,11 +694,26 @@ NTSTATUS TCPClose
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Connection->AddressFile)
|
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);
|
UnlockObject(Connection, OldIrql);
|
||||||
|
|
||||||
DereferenceObject(Connection);
|
DereferenceObject(Connection);
|
||||||
|
if (AddressConnection)
|
||||||
|
DereferenceObject(AddressConnection);
|
||||||
|
if (AddressFile)
|
||||||
|
DereferenceObject(AddressFile);
|
||||||
|
|
||||||
return Status;
|
return Status;
|
||||||
}
|
}
|
||||||
|
|
|
@ -118,8 +118,10 @@ soisconnected(so)
|
||||||
wakeup(so, (caddr_t)&head->so_timeo);
|
wakeup(so, (caddr_t)&head->so_timeo);
|
||||||
} else {
|
} else {
|
||||||
wakeup(so, (caddr_t)&so->so_timeo);
|
wakeup(so, (caddr_t)&so->so_timeo);
|
||||||
|
#ifndef __REACTOS__
|
||||||
sorwakeup(so);
|
sorwakeup(so);
|
||||||
sowwakeup(so);
|
sowwakeup(so);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,8 +133,10 @@ soisdisconnecting(so)
|
||||||
so->so_state &= ~SS_ISCONNECTING;
|
so->so_state &= ~SS_ISCONNECTING;
|
||||||
so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
|
so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
|
||||||
wakeup(so, (caddr_t)&so->so_timeo);
|
wakeup(so, (caddr_t)&so->so_timeo);
|
||||||
|
#ifndef __REACTOS__
|
||||||
sowwakeup(so);
|
sowwakeup(so);
|
||||||
sorwakeup(so);
|
sorwakeup(so);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -144,8 +148,10 @@ soisdisconnected(so)
|
||||||
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||||
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
|
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
|
||||||
wakeup(so, (caddr_t)&so->so_timeo);
|
wakeup(so, (caddr_t)&so->so_timeo);
|
||||||
|
#ifndef __REACTOS__
|
||||||
sowwakeup(so);
|
sowwakeup(so);
|
||||||
sorwakeup(so);
|
sorwakeup(so);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -192,7 +198,9 @@ sonewconn1(head, connstatus)
|
||||||
return ((struct socket *)0);
|
return ((struct socket *)0);
|
||||||
}
|
}
|
||||||
if (connstatus) {
|
if (connstatus) {
|
||||||
|
#ifndef __REACTOS__
|
||||||
sorwakeup(head);
|
sorwakeup(head);
|
||||||
|
#endif
|
||||||
wakeup(head, (caddr_t)&head->so_timeo);
|
wakeup(head, (caddr_t)&head->so_timeo);
|
||||||
so->so_state |= connstatus;
|
so->so_state |= connstatus;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue