Line 0
Link Here
|
|
|
1 |
--- src/tun.c |
2 |
+++ src/tun.c |
3 |
@@ -895,3 +895,22 @@ ssize_t tun_read(int sockfd, void *buf, size_t len) |
4 |
return read(sockfd, buf, len); |
5 |
} |
6 |
#endif |
7 |
+ |
8 |
+#ifndef __FreeBSD__ |
9 |
+int tun_claim(int sockfd) |
10 |
+{ |
11 |
+ |
12 |
+ return (0); |
13 |
+} |
14 |
+#else |
15 |
+/* |
16 |
+ * FreeBSD has a mechanism by which a tunnel has a single controlling process, |
17 |
+ * and only that one process may close it. When the controlling process closes |
18 |
+ * the tunnel, the state is torn down. |
19 |
+ */ |
20 |
+int tun_claim(int sockfd) |
21 |
+{ |
22 |
+ |
23 |
+ return (ioctl(sockfd, TUNSIFPID, 0)); |
24 |
+} |
25 |
+#endif /* !__FreeBSD__ */ |
26 |
diff --git a/src/tun.h b/src/tun.h |
27 |
index 8acad114..9e05845b 100644 |
28 |
--- src/tun.h |
29 |
+++ src/tun.h |
30 |
@@ -35,5 +35,6 @@ struct tun_lease_st { |
31 |
|
32 |
ssize_t tun_write(int sockfd, const void *buf, size_t len); |
33 |
ssize_t tun_read(int sockfd, void *buf, size_t len); |
34 |
+int tun_claim(int sockfd); |
35 |
|
36 |
#endif |
37 |
diff --git a/src/worker-auth.c b/src/worker-auth.c |
38 |
index 7fbdeaf3..d17127fe 100644 |
39 |
--- src/worker-auth.c |
40 |
+++ src/worker-auth.c |
41 |
@@ -605,7 +605,10 @@ static int recv_cookie_auth_reply(worker_st * ws) |
42 |
case AUTH__REP__OK: |
43 |
if (socketfd != -1) { |
44 |
ws->tun_fd = socketfd; |
45 |
- |
46 |
+ if (tun_claim(ws->tun_fd) != 0) { |
47 |
+ ret = ERR_AUTH_FAIL; |
48 |
+ goto cleanup; |
49 |
+ } |
50 |
if (msg->vname == NULL || msg->config == NULL || msg->user_name == NULL || msg->sid.len != sizeof(ws->sid)) { |
51 |
ret = ERR_AUTH_FAIL; |
52 |
goto cleanup; |