Skip to content

Commit 79e77e8

Browse files
committed
feat: windows library, todo: listening fails
1 parent adb34c3 commit 79e77e8

13 files changed

+1836
-188
lines changed

libtailscale.exe

-37.8 MB
Binary file not shown.

package-lock.json

+1,350
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"dependencies": {
3+
"express": "^4.18.2",
4+
"ffi-napi": "^4.0.3",
5+
"ref-napi": "^3.0.3"
6+
}
7+
}

platform/tailscale_windows.go

+30-8
Original file line numberDiff line numberDiff line change
@@ -16,22 +16,27 @@ import (
1616
"unsafe"
1717
)
1818

19-
func GetSocketPair() ([]syscall.Handle, error) {
19+
func GetSocketPair() ([]syscall.Handle, *C.SOCKET, error) {
2020
fds := make([]syscall.Handle, 2)
2121
fds_pt := C.get_socket_pair()
2222
fds_array := (*[2]C.SOCKET)(unsafe.Pointer(fds_pt))[:]
2323
fds[0] = syscall.Handle(uintptr(fds_array[0]))
2424
fds[1] = syscall.Handle(uintptr(fds_array[1]))
25-
return fds, nil
25+
return fds, fds_pt, nil
2626
}
2727

2828
func CloseSocket(fd syscall.Handle) error {
2929
fmt.Println("Closing socket", fd)
3030
err := syscall.Close(fd)
31-
errCode := syscall.GetLastError()
32-
// Handle the error or print it for debugging
33-
fmt.Printf("Error closing handle: %v\n", errCode)
34-
return err
31+
if err != nil {
32+
errCode := syscall.GetLastError()
33+
// Handle the error or print it for debugging
34+
fmt.Printf("Error closing handle: %v\n", err)
35+
fmt.Printf("Errorcode: %v\n", errCode)
36+
return err
37+
}
38+
fmt.Println("Closed socket", fd)
39+
return nil
3540
}
3641

3742
func ReadSocket(fd syscall.Handle, buf *[256]byte) {
@@ -41,8 +46,25 @@ func ReadSocket(fd syscall.Handle, buf *[256]byte) {
4146

4247
func SendMessage(fd syscall.Handle, p []byte, connFd int, to syscall.Sockaddr, flags int) error {
4348
fmt.Println("Writing socket", fd)
44-
_, err := syscall.Write(fd, p)
45-
return err
49+
var written uint32
50+
err := syscall.WSAStartup(uint32(0x202), &syscall.WSAData{})
51+
if err != nil {
52+
return err
53+
}
54+
defer syscall.WSACleanup()
55+
56+
iov := syscall.WSABuf{
57+
Len: uint32(len(p)),
58+
Buf: &p[0],
59+
}
60+
var flagsUint32 uint32 = uint32(flags)
61+
err = syscall.WSASend(fd, &iov, 1, &written, flagsUint32, nil, nil)
62+
if err != nil {
63+
return err
64+
}
65+
66+
return nil
67+
4668
}
4769

4870
func Shutdown(fd syscall.Handle, how int) error {

socketpair.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -82,9 +82,11 @@ static int dumb_socketpair(SOCKET socks[2], int make_overlapped)
8282
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
8383
if (iResult != 0) {
8484
printf("failed WSA startup");
85-
return;
85+
return SOCKET_ERROR;
8686
}
8787
SOCKET listener;
88+
u_long mode = 1; // 1 to enable non-blocking socket
89+
ioctlsocket(listener, FIONBIO, &mode);
8890
int e;
8991
socklen_t addrlen = sizeof(a.inaddr);
9092
DWORD flags = (make_overlapped ? WSA_FLAG_OVERLAPPED : 0);
@@ -95,15 +97,12 @@ static int dumb_socketpair(SOCKET socks[2], int make_overlapped)
9597
return SOCKET_ERROR;
9698
}
9799
socks[0] = socks[1] = -1;
98-
printf("something");
99100
listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
100101
if (listener == -1) {
101-
printf("something2");
102102
printf("%d", WSAGetLastError());
103103
return SOCKET_ERROR;
104104
}
105105
memset(&a, 0, sizeof(a));
106-
printf("something");
107106
a.inaddr.sin_family = AF_INET;
108107
a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
109108
a.inaddr.sin_port = 0;

socketpair_handler.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@ SOCKET *get_socket_pair() {
1818

1919
spair[0] = 0;
2020
spair[1] = 0;
21-
if(dumb_socketpair(spair, 1) == SOCKET_ERROR)
21+
if(dumb_socketpair(spair, 1) == SOCKET_ERROR) {
2222
fprintf(stderr, "Init failed, creating socketpair: %s\n", strerror(errno));
2323
free(spair);
24+
return NULL;
25+
}
2426
return spair;
2527
#else
2628
return NULL;

tailscale.c

+98-26
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,18 @@
22
// SPDX-License-Identifier: BSD-3-Clause
33

44
#include "tailscale.h"
5-
#ifdef __APPLE__ || __linux__
5+
#if defined(__APPLE__) || defined(__linux__)
66
#include <sys/socket.h>
77
#elif _WIN32
88
#include <winsock2.h>
99
#include <windows.h>
1010
#include <ws2tcpip.h>
1111
#else
12+
#include <unistd.h>
1213
#endif
1314

1415
#include <stdio.h>
15-
#include <unistd.h>
16+
1617

1718
// Functions exported by Go.
1819
extern int TsnetNewServer();
@@ -63,7 +64,7 @@ int tailscale_listen(tailscale sd, const char *network, const char *addr, tailsc
6364
int tailscale_accept(tailscale_listener ld, tailscale_conn *conn_out)
6465
{
6566

66-
#ifdef __APPLE__ || __linux__
67+
#if defined(__APPLE__) || defined(__linux__)
6768
struct msghdr msg = {0};
6869

6970
char mbuf[256];
@@ -87,30 +88,101 @@ int tailscale_accept(tailscale_listener ld, tailscale_conn *conn_out)
8788
*conn_out = fd;
8889
return 0;
8990
#elif _WIN32
90-
char mbuf[256];
91-
WSABUF wsaBuf;
92-
DWORD bytesReceived;
93-
DWORD flags = 0;
94-
SOCKET fd;
95-
96-
wsaBuf.buf = mbuf;
97-
wsaBuf.len = sizeof(mbuf);
98-
99-
if (WSARecv(ld, &wsaBuf, 1, &bytesReceived, &flags, NULL, NULL) == SOCKET_ERROR)
100-
{
101-
// Handle error, e.g., print error message or return appropriate error code.
102-
return -1;
103-
}
10491

105-
// Extract the socket descriptor from the received control information
106-
if (WSAGetOverlappedResult(ld, NULL, &bytesReceived, FALSE, &flags) == SOCKET_ERROR)
107-
{
108-
// Handle error, e.g., print error message or return appropriate error code.
109-
return -1;
110-
}
111-
112-
fd = *(SOCKET *)mbuf;
113-
*conn_out = fd;
92+
// SOCKET ListenSocket = ld;
93+
// fd_set readfds;
94+
// struct timeval tv;
95+
// int result;
96+
97+
// // Initialize the set
98+
// FD_ZERO(&readfds);
99+
// FD_SET(ListenSocket, &readfds);
100+
101+
// // Set timeout to zero, for non-blocking operation
102+
// tv.tv_sec = 1;
103+
// tv.tv_usec = 0;
104+
105+
// result = select(ListenSocket + 1, &readfds, NULL, NULL, &tv);
106+
107+
// if (result == -1) {
108+
// printf("select failed with error: %u\n", WSAGetLastError());
109+
// } else if (result == 0) {
110+
// printf("No incoming connections\n");
111+
// } else {
112+
// printf("Socket is ready to accept a connection\n");
113+
// }
114+
// char mbuf[256];
115+
// WSABUF wsaBuf;
116+
// DWORD bytesReceived;
117+
// DWORD flags = 0;
118+
// SOCKET fd;
119+
120+
// wsaBuf.buf = mbuf;
121+
// wsaBuf.len = sizeof(mbuf);
122+
123+
// if (WSARecv(ld, &wsaBuf, 1, &bytesReceived, &flags, NULL, NULL) == SOCKET_ERROR)
124+
// {
125+
// // Print the error code
126+
// int error = WSAGetLastError();
127+
// fprintf(stderr, "WSARecv failed with error: %d\n", error);
128+
// return -1;
129+
// }
130+
131+
// // Extract the socket descriptor from the received control information
132+
// if (WSAGetOverlappedResult(ld, NULL, &bytesReceived, FALSE, &flags) == SOCKET_ERROR)
133+
// {
134+
// int error = WSAGetLastError();
135+
// fprintf(stderr, "WSAGetOverlappedResult failed with error: %d\n", error);
136+
// return -1;
137+
// }
138+
// second attemp
139+
// WSADATA wsaData;
140+
// int error = WSAStartup(MAKEWORD(2,2), &wsaData);
141+
// if (error) {
142+
// printf("WSAStartup() failed with error: %d\n", error);
143+
// return 1;
144+
// }
145+
// fd = WSAAccept(ListenSocket + 1, NULL, NULL, NULL, 0);
146+
// if (fd == INVALID_SOCKET)
147+
// {
148+
// int error = WSAGetLastError();
149+
// fprintf(stderr, "WSAAccept failed with error: %d\n", error);
150+
// //return -1;
151+
// }
152+
153+
// *conn_out = fd;
154+
// return 0;
155+
// third attempt
156+
// char mbuf[256];
157+
// WSABUF wsaBuf;
158+
// DWORD bytesReceived;
159+
// DWORD flags = 0;
160+
161+
// wsaBuf.buf = mbuf;
162+
// wsaBuf.len = sizeof(mbuf);
163+
164+
// if (WSARecv(ld, &wsaBuf, 1, &bytesReceived, &flags, NULL, NULL) == SOCKET_ERROR)
165+
// {
166+
// // Print the error code
167+
// int error = WSAGetLastError();
168+
// fprintf(stderr, "WSARecv failed with error: %d\n", error);
169+
// return -1;
170+
// }
171+
172+
// // If WSARecv succeeded, return the socket
173+
// *conn_out = ld;
174+
// return 0;
175+
struct sockaddr clientAddr;
176+
int clientAddrSize = sizeof(clientAddr);
177+
178+
// Accept incoming connection
179+
*conn_out = accept(ld, &clientAddr, &clientAddrSize);
180+
if (*conn_out == INVALID_SOCKET) {
181+
printf("Accept failed with error code: %d\n", WSAGetLastError());
182+
return -1;
183+
}
184+
185+
return 0;
114186

115187
#endif
116188
}

0 commit comments

Comments
 (0)