OpenVPN
tun_afunix.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2025 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, see <https://www.gnu.org/licenses/>.
21 */
22
23#ifdef HAVE_CONFIG_H
24#include "config.h"
25#endif
26
27#include "syshead.h"
28
29#include "tun.h"
30#include "fdmisc.h"
31#include "run_command.h"
32#include "manage.h"
33#include "win32.h"
34#include "wfp_block.h"
35#include "argv.h"
36#include "options.h"
37#include "socket.h"
38
39#ifndef WIN32
40/* Windows does implement some AF_UNIX functionality but key features
41 * like socketpair() and SOCK_DGRAM are missing */
42
43#include <string.h>
44#include <unistd.h>
45#include <sys/wait.h>
46#include <signal.h>
47#include <stdlib.h>
48
49
50static void
51tun_afunix_exec_child(const char *dev_node, struct tuntap *tt, struct env_set *env)
52{
53 const char *msgprefix = "ERROR: failure executing process for tun:";
54 struct argv argv = argv_new();
55
56 /* since we know that dev-node starts with unix: we can just skip that
57 * to get the program name */
58 const char *program = dev_node + strlen("unix:");
59
60 argv_printf(&argv, "%s", program);
61
63 if (!openvpn_waitpid_check(tt->afunix.childprocess, msgprefix, M_WARN))
64 {
65 tt->afunix.childprocess = 0;
66 }
68}
69
70void
71open_tun_afunix(struct options *o, int mtu, struct tuntap *tt, struct env_set *orig_env)
72{
73 struct gc_arena gc = gc_new();
74
75 int fds[2];
76 if (!(socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) == 0))
77 {
78 msg(M_ERR, "Cannot create socket pair for AF_UNIX socket to external "
79 "program");
80 return;
81 }
82
83
84 /* Ensure that the buffer sizes are decently sized. Otherwise macOS will
85 * just have 2048 */
86 struct socket_buffer_size newsizes = { 65536, 65536 };
87 socket_set_buffers(fds[0], &newsizes, false);
88 socket_set_buffers(fds[1], &newsizes, false);
89
90 /* Use the first file descriptor for our side and avoid passing it
91 * to the child */
92 tt->fd = fds[1];
93 set_cloexec(tt->fd);
94
95 /* Make a copy of the env, so we do not need to delete our custom
96 * environment variables later */
97 struct env_set *env = env_set_create(&gc);
98 env_set_inherit(env, orig_env);
99
100 setenv_int(env, "TUNTAP_SOCKET_FD", fds[0]);
101 setenv_str(env, "TUNTAP_DEV_TYPE", dev_type_string(o->dev, o->dev_type));
102 setenv_int(env, "TUNTAP_MTU", mtu);
104 {
105 setenv_str(env, "ifconfig_gateway", o->route_default_gateway);
106 }
107 if (o->lladdr)
108 {
109 setenv_str(env, "TUNTAP_LLADDR", o->lladdr);
110 }
111
112 tun_afunix_exec_child(o->dev_node, tt, env);
113
114 close(fds[0]);
115
116 /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
117 tt->actual_name = string_alloc("internal:af_unix", NULL);
118
119 gc_free(&gc);
120}
121
122void
124{
125 ASSERT(tt);
126 if (tt->fd >= 0)
127 {
128 close(tt->fd);
129 tt->fd = 0;
130 }
131 kill(tt->afunix.childprocess, SIGINT);
132
133 free(tt->actual_name);
134 free(tt);
135}
136
137ssize_t
138write_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
139{
140 const char *msg = "ERROR: failure during write to AF_UNIX socket: ";
142 {
143 tt->afunix.childprocess = 0;
144 return -ENXIO;
145 }
146
147 return write(tt->fd, buf, len);
148}
149
150ssize_t
151read_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
152{
153 const char *msg = "ERROR: failure during read from AF_UNIX socket: ";
155 {
156 tt->afunix.childprocess = 0;
157 }
158 /* do an actual read on the file descriptor even in the error case since
159 * we otherwise loop on this on this from select and spam the console
160 * with error messages */
161 return read(tt->fd, buf, len);
162}
163#else /* ifndef WIN32 */
164void
165open_tun_afunix(const char *dev, const char *dev_type, int mtu, struct tuntap *tt,
166 struct env_set env)
167{
168 msg(M_ERR, "AF_UNIX socket support not available on this platform");
169}
170
171void
172close_tun_afunix(struct tuntap *tt)
173{
174 /* should never be called as open_tun_afunix always fails */
175 ASSERT(0);
176}
177
178ssize_t
179write_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
180{
181 /* should never be called as open_tun_afunix always fails */
182 ASSERT(0);
183}
184
185ssize_t
186read_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
187{
188 /* should never be called as open_tun_afunix always fails */
189 ASSERT(0);
190}
191
192#endif /* ifndef WIN32 */
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition argv.c:101
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition argv.c:438
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition argv.c:87
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:649
static void gc_free(struct gc_arena *a)
Definition buffer.h:1015
static struct gc_arena gc_new(void)
Definition buffer.h:1007
void setenv_int(struct env_set *es, const char *name, int value)
Definition env_set.c:291
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition env_set.c:307
void env_set_inherit(struct env_set *es, const struct env_set *src)
Definition env_set.c:262
struct env_set * env_set_create(struct gc_arena *gc)
Definition env_set.c:156
void set_cloexec(socket_descriptor_t fd)
Definition fdmisc.c:78
@ write
@ read
#define M_ERR
Definition error.h:104
#define msg(flags,...)
Definition error.h:150
#define ASSERT(x)
Definition error.h:217
#define M_WARN
Definition error.h:90
bool openvpn_waitpid_check(pid_t pid, const char *msg_prefix, int msglevel)
Checks if a running process is still running.
int openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
#define S_NOWAITPID
instead of waiting for child process to exit and report the status, return the pid of the child proce...
Definition run_command.h:56
void socket_set_buffers(socket_descriptor_t fd, const struct socket_buffer_size *sbs, bool reduce_size)
Sets the receive and send buffer sizes of a socket descriptor.
Definition socket.c:465
pid_t childprocess
Definition tun.h:172
Definition argv.h:35
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:116
const char * dev_type
Definition options.h:319
const char * route_default_gateway
Definition options.h:429
const char * dev_node
Definition options.h:320
const char * lladdr
Definition options.h:321
const char * dev
Definition options.h:318
Definition tun.h:183
char * actual_name
Definition tun.h:207
afunix_context_t afunix
Definition tun.h:250
struct gc_arena gc
Definition test_ssl.c:154
const char * dev_type_string(const char *dev, const char *dev_type)
Definition tun.c:536
void open_tun_afunix(struct options *o, int mtu, struct tuntap *tt, struct env_set *orig_env)
Opens an AF_UNIX based tun device.
Definition tun_afunix.c:71
static void tun_afunix_exec_child(const char *dev_node, struct tuntap *tt, struct env_set *env)
Definition tun_afunix.c:51
ssize_t read_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
Reads a packet from a AF_UNIX based tun device.
Definition tun_afunix.c:151
void close_tun_afunix(struct tuntap *tt)
Closes the socket used for the AF_UNIX based device.
Definition tun_afunix.c:123
ssize_t write_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
Writes a packet to a AF_UNIX based tun device.
Definition tun_afunix.c:138