forked from tailscale/libtailscale
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtailscale.c
More file actions
151 lines (127 loc) · 3.63 KB
/
tailscale.c
File metadata and controls
151 lines (127 loc) · 3.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright (c) Tailscale Inc & AUTHORS
// SPDX-License-Identifier: BSD-3-Clause
#include "tailscale.h"
#ifdef __APPLE__ || __linux__
#include <sys/socket.h>
#elif _WIN32
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#else
#endif
#include <stdio.h>
#include <unistd.h>
// Functions exported by Go.
extern int TsnetNewServer();
extern int TsnetStart(int sd);
extern int TsnetUp(int sd);
extern int TsnetClose(int sd);
extern int TsnetErrmsg(int sd, char *buf, size_t buflen);
extern int TsnetDial(int sd, char *net, char *addr, int *connOut);
extern int TsnetSetDir(int sd, char *str);
extern int TsnetSetHostname(int sd, char *str);
extern int TsnetSetAuthKey(int sd, char *str);
extern int TsnetSetControlURL(int sd, char *str);
extern int TsnetSetEphemeral(int sd, int ephemeral);
extern int TsnetSetLogFD(int sd, int fd);
extern int TsnetListen(int sd, char *net, char *addr, int *listenerOut);
extern int TsnetLoopback(int sd, char *addrOut, size_t addrLen, char *proxyOut, char *localOut);
tailscale tailscale_new()
{
return TsnetNewServer();
}
int tailscale_start(tailscale sd)
{
return TsnetStart(sd);
}
int tailscale_up(tailscale sd)
{
return TsnetUp(sd);
}
int tailscale_close(tailscale sd)
{
return TsnetClose(sd);
}
int tailscale_dial(tailscale sd, const char *network, const char *addr, tailscale_conn *conn_out)
{
return TsnetDial(sd, (char *)network, (char *)addr, (int *)conn_out);
}
int tailscale_listen(tailscale sd, const char *network, const char *addr, tailscale_listener *listener_out)
{
return TsnetListen(sd, (char *)network, (char *)addr, (int *)listener_out);
}
int tailscale_accept(tailscale_listener ld, tailscale_conn *conn_out)
{
#ifdef __APPLE__ || __linux__
struct msghdr msg = {0};
char mbuf[256];
struct iovec io = {.iov_base = mbuf, .iov_len = sizeof(mbuf)};
msg.msg_iov = &io;
msg.msg_iovlen = 1;
char cbuf[256];
msg.msg_control = cbuf;
msg.msg_controllen = sizeof(cbuf);
if (recvmsg(ld, &msg, 0) == -1)
{
return -1;
}
struct cmsghdr *cmsg = CMSG_FIRSTHDR(&msg);
unsigned char *data = CMSG_DATA(cmsg);
int fd = *(int *)data;
*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;
#endif
}
int tailscale_set_dir(tailscale sd, const char *dir)
{
return TsnetSetDir(sd, (char *)dir);
}
int tailscale_set_hostname(tailscale sd, const char *hostname)
{
return TsnetSetHostname(sd, (char *)hostname);
}
int tailscale_set_authkey(tailscale sd, const char *authkey)
{
return TsnetSetAuthKey(sd, (char *)authkey);
}
int tailscale_set_control_url(tailscale sd, const char *control_url)
{
return TsnetSetControlURL(sd, (char *)control_url);
}
int tailscale_set_ephemeral(tailscale sd, int ephemeral)
{
return TsnetSetEphemeral(sd, ephemeral);
}
int tailscale_set_logfd(tailscale sd, int fd)
{
return TsnetSetLogFD(sd, fd);
}
int tailscale_loopback(tailscale sd, char *addr_out, size_t addrlen, char *proxy_cred_out, char *local_api_cred_out)
{
return TsnetLoopback(sd, addr_out, addrlen, proxy_cred_out, local_api_cred_out);
}
int tailscale_errmsg(tailscale sd, char *buf, size_t buflen)
{
return TsnetErrmsg(sd, buf, buflen);
}