Skip to content

Commit

Permalink
feat: windows library, todo: listening fails
Browse files Browse the repository at this point in the history
  • Loading branch information
SCLevi committed Feb 7, 2024
1 parent adb34c3 commit 2880744
Show file tree
Hide file tree
Showing 13 changed files with 1,836 additions and 188 deletions.
Binary file removed libtailscale.exe
Binary file not shown.
1,350 changes: 1,350 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"dependencies": {
"express": "^4.18.2",
"ffi-napi": "^4.0.3",
"ref-napi": "^3.0.3"
}
}
38 changes: 30 additions & 8 deletions platform/tailscale_windows.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,27 @@ import (
"unsafe"
)

func GetSocketPair() ([]syscall.Handle, error) {
func GetSocketPair() ([]syscall.Handle, *C.SOCKET, error) {
fds := make([]syscall.Handle, 2)
fds_pt := C.get_socket_pair()
fds_array := (*[2]C.SOCKET)(unsafe.Pointer(fds_pt))[:]
fds[0] = syscall.Handle(uintptr(fds_array[0]))
fds[1] = syscall.Handle(uintptr(fds_array[1]))
return fds, nil
return fds, fds_pt, nil
}

func CloseSocket(fd syscall.Handle) error {
fmt.Println("Closing socket", fd)
err := syscall.Close(fd)
errCode := syscall.GetLastError()
// Handle the error or print it for debugging
fmt.Printf("Error closing handle: %v\n", errCode)
return err
if err != nil {
errCode := syscall.GetLastError()
// Handle the error or print it for debugging
fmt.Printf("Error closing handle: %v\n", err)
fmt.Printf("Errorcode: %v\n", errCode)
return err
}
fmt.Println("Closed socket", fd)
return nil
}

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

func SendMessage(fd syscall.Handle, p []byte, connFd int, to syscall.Sockaddr, flags int) error {
fmt.Println("Writing socket", fd)
_, err := syscall.Write(fd, p)
return err
var written uint32
err := syscall.WSAStartup(uint32(0x202), &syscall.WSAData{})
if err != nil {
return err
}
defer syscall.WSACleanup()

iov := syscall.WSABuf{
Len: uint32(len(p)),
Buf: &p[0],
}
var flagsUint32 uint32 = uint32(flags)
err = syscall.WSASend(fd, &iov, 1, &written, flagsUint32, nil, nil)
if err != nil {
return err
}

return nil

}

func Shutdown(fd syscall.Handle, how int) error {
Expand Down
7 changes: 3 additions & 4 deletions socketpair.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,11 @@ static int dumb_socketpair(SOCKET socks[2], int make_overlapped)
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
if (iResult != 0) {
printf("failed WSA startup");
return;
return SOCKET_ERROR;
}
SOCKET listener;
u_long mode = 1; // 1 to enable non-blocking socket
ioctlsocket(listener, FIONBIO, &mode);
int e;
socklen_t addrlen = sizeof(a.inaddr);
DWORD flags = (make_overlapped ? WSA_FLAG_OVERLAPPED : 0);
Expand All @@ -95,15 +97,12 @@ static int dumb_socketpair(SOCKET socks[2], int make_overlapped)
return SOCKET_ERROR;
}
socks[0] = socks[1] = -1;
printf("something");
listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if (listener == -1) {
printf("something2");
printf("%d", WSAGetLastError());
return SOCKET_ERROR;
}
memset(&a, 0, sizeof(a));
printf("something");
a.inaddr.sin_family = AF_INET;
a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
a.inaddr.sin_port = 0;
Expand Down
4 changes: 3 additions & 1 deletion socketpair_handler.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ SOCKET *get_socket_pair() {

spair[0] = 0;
spair[1] = 0;
if(dumb_socketpair(spair, 1) == SOCKET_ERROR)
if(dumb_socketpair(spair, 1) == SOCKET_ERROR) {
fprintf(stderr, "Init failed, creating socketpair: %s\n", strerror(errno));
free(spair);
return NULL;
}
return spair;
#else
return NULL;
Expand Down
124 changes: 98 additions & 26 deletions tailscale.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,18 @@
// SPDX-License-Identifier: BSD-3-Clause

#include "tailscale.h"
#ifdef __APPLE__ || __linux__
#if defined(__APPLE__) || defined(__linux__)
#include <sys/socket.h>
#elif _WIN32
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#else
#include <unistd.h>
#endif

#include <stdio.h>
#include <unistd.h>


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

#ifdef __APPLE__ || __linux__
#if defined(__APPLE__) || defined(__linux__)
struct msghdr msg = {0};

char mbuf[256];
Expand All @@ -87,30 +88,101 @@ int tailscale_accept(tailscale_listener ld, tailscale_conn *conn_out)
*conn_out = fd;
return 0;
#elif _WIN32
char mbuf[256];
WSABUF wsaBuf;
DWORD bytesReceived;
DWORD flags = 0;
SOCKET fd;

wsaBuf.buf = mbuf;
wsaBuf.len = sizeof(mbuf);

if (WSARecv(ld, &wsaBuf, 1, &bytesReceived, &flags, NULL, NULL) == SOCKET_ERROR)
{
// Handle error, e.g., print error message or return appropriate error code.
return -1;
}

// Extract the socket descriptor from the received control information
if (WSAGetOverlappedResult(ld, NULL, &bytesReceived, FALSE, &flags) == SOCKET_ERROR)
{
// Handle error, e.g., print error message or return appropriate error code.
return -1;
}

fd = *(SOCKET *)mbuf;
*conn_out = fd;
// SOCKET ListenSocket = ld;
// fd_set readfds;
// struct timeval tv;
// int result;

// // Initialize the set
// FD_ZERO(&readfds);
// FD_SET(ListenSocket, &readfds);

// // Set timeout to zero, for non-blocking operation
// tv.tv_sec = 1;
// tv.tv_usec = 0;

// result = select(ListenSocket + 1, &readfds, NULL, NULL, &tv);

// if (result == -1) {
// printf("select failed with error: %u\n", WSAGetLastError());
// } else if (result == 0) {
// printf("No incoming connections\n");
// } else {
// printf("Socket is ready to accept a connection\n");
// }
// char mbuf[256];
// WSABUF wsaBuf;
// DWORD bytesReceived;
// DWORD flags = 0;
// SOCKET fd;

// wsaBuf.buf = mbuf;
// wsaBuf.len = sizeof(mbuf);

// if (WSARecv(ld, &wsaBuf, 1, &bytesReceived, &flags, NULL, NULL) == SOCKET_ERROR)
// {
// // Print the error code
// int error = WSAGetLastError();
// fprintf(stderr, "WSARecv failed with error: %d\n", error);
// return -1;
// }

// // Extract the socket descriptor from the received control information
// if (WSAGetOverlappedResult(ld, NULL, &bytesReceived, FALSE, &flags) == SOCKET_ERROR)
// {
// int error = WSAGetLastError();
// fprintf(stderr, "WSAGetOverlappedResult failed with error: %d\n", error);
// return -1;
// }
// second attemp
// WSADATA wsaData;
// int error = WSAStartup(MAKEWORD(2,2), &wsaData);
// if (error) {
// printf("WSAStartup() failed with error: %d\n", error);
// return 1;
// }
// fd = WSAAccept(ListenSocket + 1, NULL, NULL, NULL, 0);
// if (fd == INVALID_SOCKET)
// {
// int error = WSAGetLastError();
// fprintf(stderr, "WSAAccept failed with error: %d\n", error);
// //return -1;
// }

// *conn_out = fd;
// return 0;
// third attempt
// char mbuf[256];
// WSABUF wsaBuf;
// DWORD bytesReceived;
// DWORD flags = 0;

// wsaBuf.buf = mbuf;
// wsaBuf.len = sizeof(mbuf);

// if (WSARecv(ld, &wsaBuf, 1, &bytesReceived, &flags, NULL, NULL) == SOCKET_ERROR)
// {
// // Print the error code
// int error = WSAGetLastError();
// fprintf(stderr, "WSARecv failed with error: %d\n", error);
// return -1;
// }

// // If WSARecv succeeded, return the socket
// *conn_out = ld;
// return 0;
struct sockaddr clientAddr;
int clientAddrSize = sizeof(clientAddr);

// Accept incoming connection
*conn_out = accept(ld, &clientAddr, &clientAddrSize);
if (*conn_out == INVALID_SOCKET) {
printf("Accept failed with error code: %d\n", WSAGetLastError());
return -1;
}

return 0;

#endif
}
Expand Down
Loading

0 comments on commit 2880744

Please sign in to comment.