Skip to content

Commit adb34c3

Browse files
committed
fix: windows porting - close socket fails
1 parent 1ac4fe3 commit adb34c3

File tree

7 files changed

+65
-34
lines changed

7 files changed

+65
-34
lines changed

go.work.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
2+
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
13
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
24
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
35
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8=

libtailscale.exe

37.8 MB
Binary file not shown.

platform/tailscale_windows.go

Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
// or OS+any architecture respectively without needing a special comment
55
package platform
66

7+
//#cgo CFLAGS: -g -Wall
78
//#cgo LDFLAGS: -lws2_32
89
//#include "errno.h"
910
//#include "../socketpair_handler.h"
@@ -15,29 +16,35 @@ import (
1516
"unsafe"
1617
)
1718

18-
func GetSocketPair() ([2]int, error) {
19-
var fds [2]int
19+
func GetSocketPair() ([]syscall.Handle, error) {
20+
fds := make([]syscall.Handle, 2)
2021
fds_pt := C.get_socket_pair()
21-
fds_array := (*[1 << 30]int)(unsafe.Pointer(fds_pt))[:2:2]
22-
fds[0] = fds_array[0]
23-
fds[1] = fds_array[1]
22+
fds_array := (*[2]C.SOCKET)(unsafe.Pointer(fds_pt))[:]
23+
fds[0] = syscall.Handle(uintptr(fds_array[0]))
24+
fds[1] = syscall.Handle(uintptr(fds_array[1]))
2425
return fds, nil
2526
}
2627

27-
func CloseSocket(fd interface{}) error {
28-
fmt.Println("Closing socket", fd.(syscall.Handle))
29-
return syscall.Close(fd.(syscall.Handle))
28+
func CloseSocket(fd syscall.Handle) error {
29+
fmt.Println("Closing socket", fd)
30+
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
3035
}
3136

32-
func ReadSocket(fd interface{}, buf *[256]byte) {
33-
syscall.Read(fd.(syscall.Handle), (*buf)[:])
37+
func ReadSocket(fd syscall.Handle, buf *[256]byte) {
38+
fmt.Println("Reading socket", fd)
39+
syscall.Read(fd, (*buf)[:])
3440
}
3541

36-
func SendMessage(fd interface{}, p []byte, connFd int, to syscall.Sockaddr, flags int) error {
37-
_, err := syscall.Write(fd.(syscall.Handle), p)
42+
func SendMessage(fd syscall.Handle, p []byte, connFd int, to syscall.Sockaddr, flags int) error {
43+
fmt.Println("Writing socket", fd)
44+
_, err := syscall.Write(fd, p)
3845
return err
3946
}
4047

41-
func Shutdown(fd interface{}, how int) error {
42-
return syscall.Shutdown(fd.(syscall.Handle), how)
48+
func Shutdown(fd syscall.Handle, how int) error {
49+
return syscall.Shutdown(fd, how)
4350
}

socketpair.c

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
4949
*/
5050

5151
#include <string.h>
52+
#include <stdio.h>
5253

5354
#ifdef _WIN32
5455
# include <ws2tcpip.h> /* socklen_t, et al (MSVC20xx) */
@@ -76,23 +77,33 @@ static int dumb_socketpair(SOCKET socks[2], int make_overlapped)
7677
struct sockaddr_in inaddr;
7778
struct sockaddr addr;
7879
} a;
80+
int iResult;
81+
WSADATA wsaData;
82+
iResult = WSAStartup(MAKEWORD(2,2), &wsaData);
83+
if (iResult != 0) {
84+
printf("failed WSA startup");
85+
return;
86+
}
7987
SOCKET listener;
8088
int e;
8189
socklen_t addrlen = sizeof(a.inaddr);
8290
DWORD flags = (make_overlapped ? WSA_FLAG_OVERLAPPED : 0);
8391
int reuse = 1;
84-
92+
8593
if (socks == 0) {
8694
WSASetLastError(WSAEINVAL);
8795
return SOCKET_ERROR;
8896
}
8997
socks[0] = socks[1] = -1;
90-
98+
printf("something");
9199
listener = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
92-
if (listener == -1)
100+
if (listener == -1) {
101+
printf("something2");
102+
printf("%d", WSAGetLastError());
93103
return SOCKET_ERROR;
94-
104+
}
95105
memset(&a, 0, sizeof(a));
106+
printf("something");
96107
a.inaddr.sin_family = AF_INET;
97108
a.inaddr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
98109
a.inaddr.sin_port = 0;
@@ -124,17 +135,17 @@ static int dumb_socketpair(SOCKET socks[2], int make_overlapped)
124135
socks[1] = accept(listener, NULL, NULL);
125136
if (socks[1] == -1)
126137
break;
127-
138+
WSACleanup();
128139
closesocket(listener);
129140
return 0;
130141
}
131-
132142
e = WSAGetLastError();
133143
closesocket(listener);
134144
closesocket(socks[0]);
135145
closesocket(socks[1]);
136146
WSASetLastError(e);
137147
socks[0] = socks[1] = -1;
148+
WSACleanup();
138149
return SOCKET_ERROR;
139150
}
140151
#else

socketpair_handler.c

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#ifdef _WIN32
2+
#include "socketpair_handler.h"
23
#include "socketpair.c"
34
#include <winsock2.h>
45
#include <windows.h>
@@ -7,14 +8,23 @@
78
#pragma comment(lib, "ws2_32.lib")
89
#endif
910

10-
int *get_socket_pair() {
11+
SOCKET *get_socket_pair() {
1112
#ifdef _WIN32
12-
SOCKET spair[2];
13+
SOCKET* spair = (SOCKET*)malloc(2 * sizeof(SOCKET));
14+
if (spair == NULL) {
15+
fprintf(stderr, "Failed to allocate memory for socket pair\n");
16+
return NULL;
17+
}
18+
1319
spair[0] = 0;
1420
spair[1] = 0;
1521
if(dumb_socketpair(spair, 1) == SOCKET_ERROR)
1622
fprintf(stderr, "Init failed, creating socketpair: %s\n", strerror(errno));
23+
free(spair);
1724
return spair;
25+
#else
26+
return NULL;
1827
#endif
19-
return -1;
28+
29+
2030
}

socketpair_handler.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#ifndef SOCKET_H
22
#define SOCKET_H
33

4-
int *get_socket_pair();
4+
#include<winsock2.h>
5+
6+
SOCKET *get_socket_pair();
57

68
#endif

tailscale.go

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ var listeners struct {
5959
type listener struct {
6060
s *server
6161
ln net.Listener
62-
fd int // go side fd of socketpair sent to C
62+
fd C.SOCKET // go side fd of socketpair sent to C
6363
}
6464

6565
// conns tracks all the pipe(2)s allocated via tsnet_dial.
@@ -172,6 +172,7 @@ func TsnetErrmsg(sd C.int, buf *C.char, buflen C.size_t) C.int {
172172

173173
//export TsnetListen
174174
func TsnetListen(sd C.int, network, addr *C.char, listenerOut *C.int) C.int {
175+
fmt.Println("start listening")
175176
s, err := getServer(sd)
176177
if err != nil {
177178
return s.recErr(err)
@@ -187,8 +188,7 @@ func TsnetListen(sd C.int, network, addr *C.char, listenerOut *C.int) C.int {
187188
// feed an fd for the connection through the listener. This lets C use
188189
// epoll on the tailscale_listener to know if it should call
189190
// tailscale_accept, which avoids a blocking call on the far side.
190-
var fds [2]int
191-
fds, err = platform.GetSocketPair()
191+
fds, err := platform.GetSocketPair()
192192

193193
if err != nil {
194194
return s.recErr(err)
@@ -200,9 +200,9 @@ func TsnetListen(sd C.int, network, addr *C.char, listenerOut *C.int) C.int {
200200
if listeners.m == nil {
201201
listeners.m = map[C.int]*listener{}
202202
}
203-
listeners.m[fdC] = &listener{s: s, ln: ln, fd: sp}
203+
listeners.m[fdC] = &listener{s: s, ln: ln, fd: C.SOCKET(sp)}
204204
listeners.mu.Unlock()
205-
205+
fmt.Println("listener setup")
206206
cleanup := func() {
207207
// If fdC is closed on the C side, then we end up calling
208208
// into cleanup twice. Be careful to avoid syscall.Close
@@ -252,7 +252,7 @@ func TsnetListen(sd C.int, network, addr *C.char, listenerOut *C.int) C.int {
252252
netConn.Close()
253253
// fallthrough to close connFd, then continue Accept()ing
254254
}
255-
platform.CloseSocket(int(connFd)) // now owned by recvmsg
255+
//platform.CloseSocket(connFd) // now owned by recvmsg
256256
}
257257
}()
258258

@@ -263,9 +263,8 @@ func TsnetListen(sd C.int, network, addr *C.char, listenerOut *C.int) C.int {
263263
func newConn(s *server, netConn net.Conn, connOut *C.int) error {
264264

265265
// TODO https://github.com/ncm/selectable-socketpair/blob/master/socketpair.c
266-
var fds [2]int
267266
var err error
268-
fds, err = platform.GetSocketPair()
267+
fds, err := platform.GetSocketPair()
269268
if err != nil {
270269
return err
271270
}
@@ -300,7 +299,7 @@ func newConn(s *server, netConn net.Conn, connOut *C.int) error {
300299
defer connCleanup()
301300
var b [1 << 16]byte
302301
io.CopyBuffer(r, netConn, b[:])
303-
platform.Shutdown(int(r.Fd()), syscall.SHUT_WR)
302+
platform.Shutdown(syscall.Handle(r.Fd()), syscall.SHUT_WR)
304303
if cr, ok := netConn.(interface{ CloseRead() error }); ok {
305304
cr.CloseRead()
306305
}
@@ -309,7 +308,7 @@ func newConn(s *server, netConn net.Conn, connOut *C.int) error {
309308
defer connCleanup()
310309
var b [1 << 16]byte
311310
io.CopyBuffer(netConn, r, b[:])
312-
platform.Shutdown(int(r.Fd()), syscall.SHUT_RD)
311+
platform.Shutdown(syscall.Handle(r.Fd()), syscall.SHUT_RD)
313312
if cw, ok := netConn.(interface{ CloseWrite() error }); ok {
314313
cw.CloseWrite()
315314
}

0 commit comments

Comments
 (0)