Skip to content
This repository has been archived by the owner on Jan 6, 2022. It is now read-only.

Commit

Permalink
Fix TUNTAP error 995 on device reset
Browse files Browse the repository at this point in the history
  • Loading branch information
mxre committed May 22, 2018
1 parent 354d5b2 commit ac8462e
Show file tree
Hide file tree
Showing 3 changed files with 70 additions and 2 deletions.
11 changes: 10 additions & 1 deletion edge.c
Original file line number Diff line number Diff line change
Expand Up @@ -1338,7 +1338,7 @@ static void readFromTAPSocket( n2n_edge_t * eee )
uint8_t eth_pkt[N2N_PKT_BUF_SIZE];
macstr_t mac_buf;
ssize_t len;

retry:
len = tuntap_read( &(eee->device), eth_pkt, N2N_PKT_BUF_SIZE );

if( (len <= 0) || (len > N2N_PKT_BUF_SIZE) )
Expand All @@ -1348,6 +1348,15 @@ static void readFromTAPSocket( n2n_edge_t * eee )
W32_ERROR(err, error);
traceEvent(TRACE_WARNING, "read()=%d [%d/%ls]", (signed int)len, err, error);
W32_ERROR_FREE(error);
if (ERROR_OPERATION_ABORTED == err) {
retry2:
traceEvent(TRACE_NORMAL, "Restart TAP device");
if (tuntap_restart( &eee->device ) < 0) {
Sleep(2000);
goto retry2;
}
goto retry;
}
#else
traceEvent(TRACE_WARNING, "read()=%d [%d/%s]", (signed int)len, errno, strerror(errno));
#endif
Expand Down
3 changes: 3 additions & 0 deletions win32/n2n_win32.h
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ typedef struct tuntap_dev {
NET_IFINDEX ifIdx;
NET_LUID luid;
OVERLAPPED overlap_read, overlap_write;
short dyn_ip4;
uint8_t mac_addr[6];
uint32_t ip_addr, device_mask;
struct in6_addr ip6_addr;
Expand All @@ -105,5 +106,7 @@ void initWin32();

int scm_startup(wchar_t* name);

int tuntap_restart( tuntap_dev* device );

#endif /* _WIN32 */
#endif
58 changes: 57 additions & 1 deletion win32/wintap.c
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,7 @@ int tuntap_open(struct tuntap_dev *device, struct tuntap_config* config) {
memcpy(&device->ip6_addr, &config->ip6_addr, sizeof(config->ip6_addr));
device->ip6_prefixlen = config->ip6_prefixlen;
device->mtu = config->mtu;
device->dyn_ip4 = config->dyn_ip4;

traceEvent(TRACE_NORMAL, "Interface %ls has MAC %s", adaptername, macaddr_str(mac_addr_buf, device->mac_addr));
#if 0
Expand All @@ -296,7 +297,7 @@ int tuntap_open(struct tuntap_dev *device, struct tuntap_config* config) {

/* printf("Setting %ls device address...\n", device->device_name); */

if (config->dyn_ip4) {
if (device->dyn_ip4) {
rc = set_dhcp(device);
} else {
rc = set_static_ip_address(device);
Expand Down Expand Up @@ -404,6 +405,61 @@ void tuntap_close(struct tuntap_dev *tuntap) {
CloseHandle(tuntap->device_handle);
}

int tuntap_restart( tuntap_dev* device ) {
WCHAR tapname[MAX_PATH];
ULONG status = TRUE;
DWORD rc;
long len;

CloseHandle(device->device_handle);

ResetEvent(device->overlap_write.hEvent);
ResetEvent(device->overlap_read.hEvent);

swprintf(tapname, sizeof(tapname), USERMODEDEVICEDIR "%s" TAP_WIN_SUFFIX, device->device_name);
device->device_handle = CreateFile(
tapname, GENERIC_WRITE | GENERIC_READ,
0, /* Don't let other processes share or open the resource until the handle's been closed */
0, OPEN_EXISTING, FILE_ATTRIBUTE_SYSTEM | FILE_FLAG_OVERLAPPED, 0
);
if(device->device_handle == INVALID_HANDLE_VALUE) {
W32_ERROR(GetLastError(), error)
traceEvent(TRACE_ERROR, "Unable to reopen TAP adapter %ls: %ls", device->device_name, error);
W32_ERROR_FREE(error)
return -1;
}

if (device->dyn_ip4) {
rc = set_dhcp(device);
} else {
rc = set_static_ip_address(device);
}

if (rc == 0) {
tuntap_get_address(device);
} else {
W32_ERROR(rc, error)
traceEvent(TRACE_WARNING, "Unable to set device %ls IP address: %u", device->device_name, error);
W32_ERROR_FREE(error)
}

if(device->mtu != DEFAULT_MTU)
traceEvent(TRACE_WARNING, "MTU set is not supported on Windows");

if (!DeviceIoControl(
device->device_handle, TAP_WIN_IOCTL_SET_MEDIA_STATUS,
&status, sizeof (status),
&status, sizeof (status), &len, NULL
)) {
W32_ERROR(GetLastError(), error);
traceEvent(TRACE_ERROR, "Unable to enable TAP adapter %ls: %ls", device->device_name, error);
W32_ERROR_FREE(error);
return -1;
}

return 0;
}

/* Fill out the ip_addr value from the interface. Called to pick up dynamic
* address changes. */
void tuntap_get_address(struct tuntap_dev *tuntap) {
Expand Down

0 comments on commit ac8462e

Please sign in to comment.