Skip to content

Commit 1ac4fe3

Browse files
committed
feat: separate golang code by platforms
1 parent e361578 commit 1ac4fe3

File tree

7 files changed

+100
-31
lines changed

7 files changed

+100
-31
lines changed

go.work

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
go 1.21.6
2+
3+
use .

go.work.sum

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
2+
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
3+
github.com/tailscale/hujson v0.0.0-20221223112325-20486734a56a/go.mod h1:DFSS3NAGHthKo1gTlmEcSBiZrRJXi28rLNd/1udP1c8=
4+
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=

platform/tailscale_unix.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//go:build darwin || linux
2+
// +build darwin linux
3+
4+
package platform
5+
6+
//#include "errno.h"
7+
//#include "../socketpair_handler.h"
8+
import "C"
9+
10+
import (
11+
"syscall"
12+
)
13+
14+
func GetSocketPair() ([2]int, error) {
15+
return syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
16+
}
17+
18+
func CloseSocket(fd interface{}) (err error) {
19+
return syscall.Close(fd.(int))
20+
}
21+
22+
func ReadSocket(fd interface{}, buf *[256]byte) {
23+
syscall.Read(fd.(int), (*buf)[:])
24+
}
25+
26+
func SendMessage(fd interface{}, p []byte, connFd int, to syscall.Sockaddr, flags int) (err error) {
27+
rights := syscall.UnixRights(int(connFd))
28+
return syscall.Sendmsg(fd.(int), p, rights, to, flags)
29+
}
30+
31+
func Shutdown(fd interface{}, how int) (err error) {
32+
return syscall.Shutdown(fd.(int), how)
33+
}

platform/tailscale_windows.go

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// If your file name follows the structure name_{GOOS}_{GOARCH}.go or
2+
// simply name_{GOOS}.go,
3+
// then it will be compiled only under the target OS+architecture
4+
// or OS+any architecture respectively without needing a special comment
5+
package platform
6+
7+
//#cgo LDFLAGS: -lws2_32
8+
//#include "errno.h"
9+
//#include "../socketpair_handler.h"
10+
import "C"
11+
12+
import (
13+
"fmt"
14+
"syscall"
15+
"unsafe"
16+
)
17+
18+
func GetSocketPair() ([2]int, error) {
19+
var fds [2]int
20+
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]
24+
return fds, nil
25+
}
26+
27+
func CloseSocket(fd interface{}) error {
28+
fmt.Println("Closing socket", fd.(syscall.Handle))
29+
return syscall.Close(fd.(syscall.Handle))
30+
}
31+
32+
func ReadSocket(fd interface{}, buf *[256]byte) {
33+
syscall.Read(fd.(syscall.Handle), (*buf)[:])
34+
}
35+
36+
func SendMessage(fd interface{}, p []byte, connFd int, to syscall.Sockaddr, flags int) error {
37+
_, err := syscall.Write(fd.(syscall.Handle), p)
38+
return err
39+
}
40+
41+
func Shutdown(fd interface{}, how int) error {
42+
return syscall.Shutdown(fd.(syscall.Handle), how)
43+
}

socketpair.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
5050

5151
#include <string.h>
5252

53-
#ifdef WIN32
53+
#ifdef _WIN32
5454
# include <ws2tcpip.h> /* socklen_t, et al (MSVC20xx) */
5555
# include <windows.h>
5656
# include <io.h>
@@ -60,7 +60,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
6060
# include <errno.h>
6161
#endif
6262

63-
#ifdef WIN32
63+
#ifdef _WIN32
6464

6565
/* dumb_socketpair:
6666
* If make_overlapped is nonzero, both sockets created will be usable for
@@ -70,7 +70,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
7070
* sockets must be closed with closesocket() regardless.
7171
*/
7272

73-
int dumb_socketpair(SOCKET socks[2], int make_overlapped)
73+
static int dumb_socketpair(SOCKET socks[2], int make_overlapped)
7474
{
7575
union {
7676
struct sockaddr_in inaddr;
@@ -138,7 +138,7 @@ int dumb_socketpair(SOCKET socks[2], int make_overlapped)
138138
return SOCKET_ERROR;
139139
}
140140
#else
141-
int dumb_socketpair(int socks[2], int dummy)
141+
static int dumb_socketpair(int socks[2], int dummy)
142142
{
143143
if (socks == 0) {
144144
errno = EINVAL;

socketpair_handler.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <windows.h>
55
#include <ws2tcpip.h>
66
#include <stdio.h>
7+
#pragma comment(lib, "ws2_32.lib")
78
#endif
89

910
int *get_socket_pair() {

tailscale.go

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ import (
1818
"syscall"
1919
"unsafe"
2020

21+
"github.com/tailscale/libtailscale/platform"
22+
2123
"tailscale.com/hostinfo"
2224
"tailscale.com/tsnet"
2325
"tailscale.com/types/logger"
@@ -186,14 +188,8 @@ func TsnetListen(sd C.int, network, addr *C.char, listenerOut *C.int) C.int {
186188
// epoll on the tailscale_listener to know if it should call
187189
// tailscale_accept, which avoids a blocking call on the far side.
188190
var fds [2]int
189-
if os.Getenv("GOOS") == "windows" {
190-
fds_pt := C.get_socket_pair()
191-
fds_array := (*[1 << 30]int)(unsafe.Pointer(fds_pt))[:2:2]
192-
fds[0] = fds_array[0]
193-
fds[1] = fds_array[1]
194-
} else {
195-
fds, err = syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
196-
}
191+
fds, err = platform.GetSocketPair()
192+
197193
if err != nil {
198194
return s.recErr(err)
199195
}
@@ -214,7 +210,7 @@ func TsnetListen(sd C.int, network, addr *C.char, listenerOut *C.int) C.int {
214210
listeners.mu.Lock()
215211
if tsLn, ok := listeners.m[fdC]; ok && tsLn.ln == ln {
216212
delete(listeners.m, fdC)
217-
syscall.Close(sp)
213+
platform.CloseSocket(sp)
218214
}
219215
listeners.mu.Unlock()
220216

@@ -227,7 +223,7 @@ func TsnetListen(sd C.int, network, addr *C.char, listenerOut *C.int) C.int {
227223
//
228224
// TODO: would using os.NewFile avoid a locked up thread?
229225
var buf [256]byte
230-
syscall.Read(sp, buf[:])
226+
platform.ReadSocket(sp, &buf)
231227
cleanup()
232228
}()
233229
go func() {
@@ -245,12 +241,8 @@ func TsnetListen(sd C.int, network, addr *C.char, listenerOut *C.int) C.int {
245241
netConn.Close()
246242
continue
247243
}
248-
if os.Getenv("GOOS") == "windows" {
249-
_, err = syscall.Write(sp, nil)
250-
} else {
251-
rights := syscall.UnixRights(int(connFd))
252-
err = syscall.Sendmsg(sp, nil, rights, nil, 0)
253-
}
244+
245+
err = platform.SendMessage(sp, nil, int(connFd), nil, 0)
254246

255247
if err != nil {
256248
// We handle sp being closed in the read goroutine above.
@@ -260,7 +252,7 @@ func TsnetListen(sd C.int, network, addr *C.char, listenerOut *C.int) C.int {
260252
netConn.Close()
261253
// fallthrough to close connFd, then continue Accept()ing
262254
}
263-
syscall.Close(int(connFd)) // now owned by recvmsg
255+
platform.CloseSocket(int(connFd)) // now owned by recvmsg
264256
}
265257
}()
266258

@@ -273,14 +265,7 @@ func newConn(s *server, netConn net.Conn, connOut *C.int) error {
273265
// TODO https://github.com/ncm/selectable-socketpair/blob/master/socketpair.c
274266
var fds [2]int
275267
var err error
276-
if os.Getenv("GOOS") == "windows" {
277-
fds_pt := C.get_socket_pair()
278-
fds_array := (*[1 << 30]int)(unsafe.Pointer(fds_pt))[:2:2]
279-
fds[0] = fds_array[0]
280-
fds[1] = fds_array[1]
281-
} else {
282-
fds, err = syscall.Socketpair(syscall.AF_LOCAL, syscall.SOCK_STREAM, 0)
283-
}
268+
fds, err = platform.GetSocketPair()
284269
if err != nil {
285270
return err
286271
}
@@ -315,7 +300,7 @@ func newConn(s *server, netConn net.Conn, connOut *C.int) error {
315300
defer connCleanup()
316301
var b [1 << 16]byte
317302
io.CopyBuffer(r, netConn, b[:])
318-
syscall.Shutdown(int(r.Fd()), syscall.SHUT_WR)
303+
platform.Shutdown(int(r.Fd()), syscall.SHUT_WR)
319304
if cr, ok := netConn.(interface{ CloseRead() error }); ok {
320305
cr.CloseRead()
321306
}
@@ -324,7 +309,7 @@ func newConn(s *server, netConn net.Conn, connOut *C.int) error {
324309
defer connCleanup()
325310
var b [1 << 16]byte
326311
io.CopyBuffer(netConn, r, b[:])
327-
syscall.Shutdown(int(r.Fd()), syscall.SHUT_RD)
312+
platform.Shutdown(int(r.Fd()), syscall.SHUT_RD)
328313
if cw, ok := netConn.(interface{ CloseWrite() error }); ok {
329314
cw.CloseWrite()
330315
}

0 commit comments

Comments
 (0)