This project is read-only.

Force Hangup

Apr 7, 2009 at 7:00 PM
I was looking at the connection hangup method.  It doesn't appear to address issues where the connection stays in a connecting state.  Do you have something that will force a hangup regardless of connection state?
Apr 7, 2009 at 7:08 PM
The HangUp method on RasConnection does force it to disconnect. There isn't a "try to disconnect" API anywhere in RAS.

If you're managing the connection yourself through the RasDialer component you can set the timeout property and dial the connection asynchronously via the DialAsync() method. The timeout automatically causes the connection to disconnect if it hasn't connected before the timeout expires.
Oct 13, 2009 at 6:22 PM
Edited Oct 13, 2009 at 6:32 PM

I think tllaugn was not referring to forcing a disconnect on a connection attempt but to ensuring the disconnection of a connection successfully created by DotRas, specifically, the documented requirement:

"The RasHangUp function terminates a remote access connection. The connection is specified with a RAS connection handle. The function releases all RASAPI32.DLL resources associated with the handle. (MSDN"

Then, in the remarks section, it is mentioned that application should sleep about 3 seconds, or until RasGetConnectStatus returns ERROR_INVALID_HANDLE. 

I believe the issue tllaugh, and myself, have experienced is if you really just call RasHangUp and exit - you can "hang" both modem and rnaapp (application that implement Dial-Up Service).  I have experienced this with creating and attempting to disconnect a VPN connection created via DotRas.

In stepping through the RasConnection.Hangup() code through to the SafeNativeMethods.RasHangup() call, I found that  an ERROR_INVALID_HANDLE value returned by the SafeNativeMethods.RasHangup() call throws an exception.  I have seen, and used, workarounds that poll and wait for ERROR_INVALID_HANDLE to be returned.  This is the only safe and reliable way I have found of ensuring that a RasConnection is properly terminated:

<tt>
 DWORD dwRet;
RASCONNSTATUS rStatus;
ZeroMemory(&rStatus, sizeof(RASCONNSTATUS));
rStatus.dwSize = sizeof(RASCONNSTATUS);
dwRet = RasGetConnectStatus(hRasConn, &rStatus);
if (dwRet != ERROR_INVALID_HANDLE)
{
RasHangUp(hRasConn); // hRasConn - valid handle to the RAS connection
MSG msg;
while (dwRet != ERROR_INVALID_HANDLE)
{
while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}

            dwRet = RasGetConnectStatus(hRasConn, &rStatus);

        }

}

</tt>

As the code above indicates, the ERROR_INVALID_HANDLE value that DotRas throws an exception on is the value that should be the sole requirement for returning NativeMethods.SUCCESS.  In short, the issue is to ensure that this happens without having to resort to interfacing directly with the RASAPI32.dll.

 

Oct 13, 2009 at 6:58 PM
Edited Oct 13, 2009 at 7:06 PM

The issue he was referring to was from an older version of the software, if you notice the date it was on April 7th. One of the potential problems noted on the RasDialer component is if your application terminates before a connection is successful, it can leave the connection in an inconsistent state that it cannot get out of until the machine is restarted. That's why I have the IDisposable interface implemented along with a finalizer on the class to ensure the connection is released before the component is disposed.

If an application attempts to hangup an invalid handle the method will throw an exception indicating the handle is invalid. This is only done in the situation where an application attempts to hangup a connection that was already disconnected from an outside source. If I simply returned false you wouldn't know the connection wasn't valid, and you may continue using it in the application causing further issues. I can't assume the handle you're trying to disconnect is valid.

In that bit of code you posted, the dwRet value that's being checked for ERROR_INVALID_HANDLE isn't being returned from the RasHangUp method, it's being checked from RasGetConnectStatus. Which the method on RasHelper which handles getting connection status will throw an exception if ERROR_INVALID_HANDLE is returned by it (which is standard by any API calls by this project), so I just opted to pause the calling thread temporarily as indicated by the SDK to allow the hangup to complete before the application could potentially terminate. When RasHangUp begins to disconnect a valid connection handle it returns success since it's an asynchronous call, not synchronous.

If the Thread.Sleep is a problem I can do a bit of refactoring on the RasGetConnectStatus helper method to allow it to be used by HangUp so I don't have to pause the thread, but as for changing HangUp to not throw an exception if an invalid handle is passed into it that is out of the question.

 

Edit: Just had to make a quick replacement on 'intermediate' to 'inconsistent' which is what was stated in the Windows SDK.

Oct 13, 2009 at 7:57 PM

Hello Jeff,

but as for changing HangUp to not throw an exception if an invalid handle is passed into it that is out of the question…

Actually, that works for me. After I uploaded my post to the DotRas Discussion Forum, I tried wrapping a finite loop of calls to RasConnection.Hangup() in a try..catch block looking specifically for an InvalidHandleException in my wrapper class. If either the loop count exceeds the maximum I defined or that specific exception is detected, I trap it and then exit from my wrapper’s Disconnect method. After implementing that this morning, I have had no problems with the VPN tunnel staying connected after returning from my wrapper class’s Disconnect() method. Thanks, again.

Erich Einfalt

Windows Developer

Anonymizer, Inc.

Trusted / Proven / Secure

858-866-1360 / Direct

858-866-0164 / Fax

eeinfalt@anonymizerinc.com

www.anonymizer.com

Anonymizer, Inc. is the global leader in non-attribution solutions ensuring customers online privacy, identity protection, and secure access to open source intelligence.

From: jeff_winn [mailto:notifications@codeplex.com]
Sent: Tuesday, October 13, 2009 10:59 AM
To: Erich Einfalt
Subject: Re: Force Hangup [DotRas:52583]

From: jeff_winn

The issue he was referring to was from an older version of the software, if you notice the date it was on April 7th. One of the potential problems noted on the RasDialer component is if your application terminates before a connection is successful, it can leave the connection in an intermediate state that it cannot get out of until the machine is restarted. That's why I have the IDisposable interface implemented along with a finalizer on the class to ensure the connection is released before the component is disposed.

If an application attempts to hangup an invalid handle the method will throw an exception indicating the handle is invalid. This is only done in case an application attempts to hangup a connection that was already disconnected from an outside source, not from DotRas. If I simply returned false you wouldn't know the connection wasn't valid, and you may continue using it in the application causing further issues. I can't assume the handle you're trying to disconnect is still valid, because it can be controlled outside of this project.

In that bit of code you posted, the dwRet value that's being checked for ERROR_INVALID_HANDLE isn't being returned from the RasHangUp method, it's being checked from RasGetConnectStatus. Which the method on RasHelper which handles getting connection status will throw an exception if ERROR_INVALID_HANDLE is returned by it (which is standard by any API calls by this project), so I just opted to pause the calling thread temporarily as indicated by the SDK to allow the hangup to complete before the application could potentially terminate. When RasHangUp begins to disconnect a valid connection handle, it returns success; this goes back to that whole asynchronous versus synchronous call I mentioned earlier.

If the Thread.Sleep is a problem I can do a bit of refactoring on the RasGetConnectStatus helper method to allow it to be used by HangUp so I don't have to pause the thread, but as for changing HangUp to not throw an exception if an invalid handle is passed into it that is out of the question.

Read the full discussion online.

To add a post to this discussion, reply to this email (DotRas@discussions.codeplex.com)

To start a new discussion for this project, email DotRas@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com



NOTICE: This email message and all attachments transmitted with it are intended solely for the use of the addressees and may contain legally privileged, protected or confidential information. If you have received this message in error, please notify the sender immediately by email reply and please delete this message from your computer and destroy any copies.
Oct 13, 2009 at 8:06 PM

Are you saying when you call hangup the connection isn't disconnected after the 3 second window as indicated by the Windows SDK?

If that's the case I can definitely do some refactoring inside the method to check RasGetConnectStatus. .NET guidelines indicate exceptions shouldn't be used to control program flow, which if you're purposefully getting DotRas to throw the exception I need to do some work on my end inside the method to make sure you don't have to. That exception is only supposed to be thrown if the connection disconnects outside of DotRas control.

Oct 13, 2009 at 8:11 PM

Hi, Jeff,

Yes, the VPN tunnel created by DotRas intermittently stays connected after the RasConnection.Hangup() method returns. It stays up more often than it shuts down. I haven’t found a discernible pattern of uses that might indicate the reason for this behavior.

Erich Einfalt

Windows Developer

Anonymizer, Inc.

Trusted / Proven / Secure

858-866-1360 / Direct

858-866-0164 / Fax

eeinfalt@anonymizerinc.com

www.anonymizer.com

Anonymizer, Inc. is the global leader in non-attribution solutions ensuring customers online privacy, identity protection, and secure access to open source intelligence.

From: jeff_winn [mailto:notifications@codeplex.com]
Sent: Tuesday, October 13, 2009 12:06 PM
To: Erich Einfalt
Subject: Re: Force Hangup [DotRas:52583]

From: jeff_winn

Are you saying when you call hangup the connection isn't disconnected after the 3 second window as indicated by the Windows SDK?

If that's the case I can definitely do some refactoring inside the method to check RasGetConnectStatus. .NET guidelines indicate exceptions shouldn't be used to control program flow, which if you're purposefully getting DotRas to throw the exception I need to do some work on my end inside the method to make sure you don't have to. That exception is only supposed to be thrown if the connection disconnects outside of DotRas control.

Read the full discussion online.

To add a post to this discussion, reply to this email (DotRas@discussions.codeplex.com)

To start a new discussion for this project, email DotRas@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com



NOTICE: This email message and all attachments transmitted with it are intended solely for the use of the addressees and may contain legally privileged, protected or confidential information. If you have received this message in error, please notify the sender immediately by email reply and please delete this message from your computer and destroy any copies.
Oct 13, 2009 at 8:27 PM

Sounds like there might be some additional latency that's causing the connection to not finish disconnection within 3 seconds, I typically test everything using a virtual server running on my box so everything is instantaneous. I was planning on hanging blinds in my house tonight, but I can take a break and do a bit of refactoring on the GetConnectionStatus method so it can be used from the HangUp method.

Keep an eye on code changes tonight from the source code tab and let me know if it helps. It'll be a few hours before I have a chance to work on it, but I should be able to get to it pretty quickly.

Oct 13, 2009 at 8:29 PM

Thanks, very much. Also, when hanging blinds, use a step stool – never a chair ;)

Erich Einfalt

Windows Developer

Anonymizer, Inc.

Trusted / Proven / Secure

858-866-1360 / Direct

858-866-0164 / Fax

eeinfalt@anonymizerinc.com

www.anonymizer.com

Anonymizer, Inc. is the global leader in non-attribution solutions ensuring customers online privacy, identity protection, and secure access to open source intelligence.

From: jeff_winn [mailto:notifications@codeplex.com]
Sent: Tuesday, October 13, 2009 12:28 PM
To: Erich Einfalt
Subject: Re: Force Hangup [DotRas:52583]

From: jeff_winn

Sounds like there might be some additional latency that's causing the connection to not finish disconnection within 3 seconds, I typically test everything using a virtual server running on my box so everything is instantaneous. I was planning on hanging blinds in my house tonight, but I can take a break and do a bit of refactoring on the GetConnectionStatus method so it can be used from the HangUp method.

Keep an eye on code changes tonight from the source code tab and let me know if it helps. It'll be a few hours before I have a chance to work on it, but I should be able to get to it pretty quickly.

Read the full discussion online.

To add a post to this discussion, reply to this email (DotRas@discussions.codeplex.com)

To start a new discussion for this project, email DotRas@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com



NOTICE: This email message and all attachments transmitted with it are intended solely for the use of the addressees and may contain legally privileged, protected or confidential information. If you have received this message in error, please notify the sender immediately by email reply and please delete this message from your computer and destroy any copies.
Oct 13, 2009 at 11:57 PM

Ok, I finished refactoring the hangup method and it should now wait indefinitely until the disconnect attempt has timed out. It has a 1 second interval on checking the connection status to prevent the processor going crazy during the disconnect attempt. Let me know if that solves your problem. It's change set 44933 (or later) you're looking for.

Oct 14, 2009 at 12:55 AM

Hi, Jeff,

The first time I attempted to terminate the connection using the changeset 44933 code changes, it never returned, had to kill the process and reboot. I’ll try it again tomorrow when the VPN server here has rebooted and step through the RasHelper.Hangup() method. Thanks, again.

Erich Einfalt

Windows Developer

Anonymizer, Inc.

Trusted / Proven / Secure

858-866-1360 / Direct

858-866-0164 / Fax

eeinfalt@anonymizerinc.com

www.anonymizer.com

Anonymizer, Inc. is the global leader in non-attribution solutions ensuring customers online privacy, identity protection, and secure access to open source intelligence.

From: jeff_winn [mailto:notifications@codeplex.com]
Sent: Tuesday, October 13, 2009 3:58 PM
To: Erich Einfalt
Subject: Re: Force Hangup [DotRas:52583]

From: jeff_winn

Ok, I finished refactoring the hangup method and it should now wait indefinitely until the disconnect attempt has timed out. It has a 1 second interval on checking the connection status to prevent the processor going crazy during the disconnect attempt. Let me know if that solves your problem. It's change set 44933 (or later) you're looking for.

Read the full discussion online.

To add a post to this discussion, reply to this email (DotRas@discussions.codeplex.com)

To start a new discussion for this project, email DotRas@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com



NOTICE: This email message and all attachments transmitted with it are intended solely for the use of the addressees and may contain legally privileged, protected or confidential information. If you have received this message in error, please notify the sender immediately by email reply and please delete this message from your computer and destroy any copies.
Oct 14, 2009 at 2:00 PM

Let me know what you find, I've checked over the code a few times and the loop should exit properly. The only thing I can think of is the call to RasGetConnectStatus is returning some other value than what was expected. It worked over here, but like I said earlier my disconnections are instantaneous so I had to step the debugger into the loop to make sure it was working correctly.

Oct 14, 2009 at 7:28 PM

Hi, Jeff.

I reran my app using DotRas changeset 44933 through the VisualStudio2008 debugger this morning after the VPN server was rebooted and the SafeNativeMethods.GetConnectStatus() call in the loop in RasHelper.HangUp() always returns zero so the loop never exits. When I changed the while condition to force the loop to exit with Edit-And-Continue, the loop does exit but the VPN connection remains active. It is not torn down upon a successful native RasHangup() as the RASAPI32 documentation claims.

Now what is strange is that when I replied to your initial response to my forum post that I tried calls to RasConnection.Hangup() in a loop that exits on trapping any exceptions that occur in that loop and that this approach worked (the VPN connection was successfully torn down upon exiting my loop), I failed to inform you that I was using v1.0 of DotRas downloaded in July or August. Using v1.1 has consistently failed to actually tear down the VPN connection using either the 3000 millisecond Sleep() call or the 44933 changeset loop that exits on GetConnectStatus == NativeMethods.ERROR_INVALID_HANDLE.

Erich Einfalt

Windows Developer

Anonymizer, Inc.

Trusted / Proven / Secure

858-866-1360 / Direct

858-866-0164 / Fax

eeinfalt@anonymizerinc.com

www.anonymizer.com

Anonymizer, Inc. is the global leader in non-attribution solutions ensuring customers online privacy, identity protection, and secure access to open source intelligence.

From: jeff_winn [mailto:notifications@codeplex.com]
Sent: Wednesday, October 14, 2009 6:01 AM
To: Erich Einfalt
Subject: Re: Force Hangup [DotRas:52583]

From: jeff_winn

Let me know what you find, I've checked over the code a few times and the loop should exit properly. The only thing I can think of is the call to RasGetConnectStatus is returning some other value than what was expected. It worked over here, but like I said earlier my disconnections are instantaneous so I had to step the debugger into the loop to make sure it was working correctly.

Read the full discussion online.

To add a post to this discussion, reply to this email (DotRas@discussions.codeplex.com)

To start a new discussion for this project, email DotRas@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com



NOTICE: This email message and all attachments transmitted with it are intended solely for the use of the addressees and may contain legally privileged, protected or confidential information. If you have received this message in error, please notify the sender immediately by email reply and please delete this message from your computer and destroy any copies.
Oct 14, 2009 at 8:01 PM

Hmm, have you tried connecting and disconnecting the entry from the network connections window in Windows? Is there anything special about this VPN connection?

I can't imagine what would be causing RasHangUp to not work correctly, it only has 1 argument on it. Unless the connection is being left in an inconsistent state somehow while you're dialing it. If it's working from the network connections window it should be working here. Try dialing the connection through Windows and then disconnecting through DotRas.

We'll start there and see what happens.

Oct 15, 2009 at 1:18 AM

Hi, Jeff.

The only thing I have had consistent success is with the following (pre changeset 44933) code with 2 modifications. The VPN tunnel releases every time when BOTH modifications are in place:

(1) It seems that the value of ret is not always NativeMethods.SUCCESS.

The VPN tunnel never releases if this condition is left in. It releases every time if it is commented out.

(2) If the handle is set as invalid, the VPN tunnel never releases. With the handle.SetHandleAsInvalid() call commented out, the VPN tunnel releases every time.

public static bool HangUp(RasHandle handle)

{

int ret = SafeNativeMethods.RasHangUp(handle);

if (ret == NativeMethods.ERROR_INVALID_HANDLE)

{

ThrowHelper.ThrowInvalidHandleException(handle, "handle", Resources.Argument_InvalidHandle);

}

else //if (ret == NativeMethods.SUCCESS)

{

Thread.Sleep(3000);

// Mark the handle as invalid to prevent it from being used elsewhere in the assembly.

//handle.SetHandleAsInvalid();

}

return ret == NativeMethods.SUCCESS;

}

Erich Einfalt

Windows Developer

Anonymizer, Inc.

Trusted / Proven / Secure

858-866-1360 / Direct

858-866-0164 / Fax

eeinfalt@anonymizerinc.com

www.anonymizer.com

Anonymizer, Inc. is the global leader in non-attribution solutions ensuring customers online privacy, identity protection, and secure access to open source intelligence.

From: jeff_winn [mailto:notifications@codeplex.com]
Sent: Wednesday, October 14, 2009 12:01 PM
To: Erich Einfalt
Subject: Re: Force Hangup [DotRas:52583]

From: jeff_winn

Hmm, have you tried connecting and disconnecting the entry from the network connections window in Windows? Is there anything special about this VPN connection?

I can't imagine what would be causing RasHangUp to not work correctly, it only has 1 argument on it. Unless the connection is being left in an inconsistent state somehow while you're dialing it. If it's working from the network connections window it should be working here. Try dialing the connection through Windows and then disconnecting through DotRas.

We'll start there and see what happens.

Read the full discussion online.

To add a post to this discussion, reply to this email (DotRas@discussions.codeplex.com)

To start a new discussion for this project, email DotRas@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com



NOTICE: This email message and all attachments transmitted with it are intended solely for the use of the addressees and may contain legally privileged, protected or confidential information. If you have received this message in error, please notify the sender immediately by email reply and please delete this message from your computer and destroy any copies.
Oct 15, 2009 at 3:11 PM

What values for ret are you seeing?

I'd like to look in the SDK what the values mean before I comment out a large section of code that people need to see what values are being returned from the RasHangUp API.

Oct 16, 2009 at 12:20 AM

Hi, Jeff.

I think the behavior I’m seeing is due to something in the way the VPN server I’m testing my app against is set up. I logged the return value from NativeMethods.RasHangup() and it’s always zero, so I restored the if (ret == NativeMethods.SUCCESS) test and the next test correctly released the VPN connection but all subsequent runs after that failed to release the VPN connection. I re-disabled the if (ret == NativeMethods.SUCCESS) test as I did yesterday when it consistently worked correctly and now that, too, fails to release the VPN connection. So until we can get this VPN server working correctly, I cannot determine if continuing to comment out the remaining call to handle.SetHandleAsInvalid() as I reported yesterday is really having any positive effect.

Erich Einfalt

Windows Developer

Anonymizer, Inc.

Trusted / Proven / Secure

858-866-1360 / Direct

858-866-0164 / Fax

eeinfalt@anonymizerinc.com

www.anonymizer.com

Anonymizer, Inc. is the global leader in non-attribution solutions ensuring customers online privacy, identity protection, and secure access to open source intelligence.

From: jeff_winn [mailto:notifications@codeplex.com]
Sent: Thursday, October 15, 2009 7:11 AM
To: Erich Einfalt
Subject: Re: Force Hangup [DotRas:52583]

From: jeff_winn

What values for ret are you seeing?

I'd like to look in the SDK what the values mean before I comment out a large section of code that people need to see what values are being returned from the RasHangUp API.

Read the full discussion online.

To add a post to this discussion, reply to this email (DotRas@discussions.codeplex.com)

To start a new discussion for this project, email DotRas@discussions.codeplex.com

You are receiving this email because you subscribed to this discussion on CodePlex. You can unsubscribe on codePlex.com.

Please note: Images and attachments will be removed from emails. Any posts to this discussion will also be available online at codeplex.com



NOTICE: This email message and all attachments transmitted with it are intended solely for the use of the addressees and may contain legally privileged, protected or confidential information. If you have received this message in error, please notify the sender immediately by email reply and please delete this message from your computer and destroy any copies.
Oct 16, 2009 at 3:45 AM

Well I guess let me know what you find out, I'm interested to see where the problem is at.

Oct 18, 2009 at 7:36 PM

FYI, I've changed HangUp again so the loop checking the connection status continues while it's returning data. If the value is anything other than success, it will exit the loop. This should prevent it from continuing indefinitely unless the connection never exits.