char *confdir = NULL; /* base configuration directory */
char *confbase = NULL; /* base configuration directory for this instance of tinc */
char *identname = NULL; /* program name for syslog */
+char *unixsocketname = NULL; /* UNIX socket location */
char *logfilename = NULL; /* log file location */
char *pidfilename = NULL;
char *program_name = NULL;
if(!pidfilename)
xasprintf(&pidfilename, LOCALSTATEDIR SLASH "run" SLASH "%s.pid", identname);
+ if(!unixsocketname)
+ xasprintf(&unixsocketname, LOCALSTATEDIR SLASH "run" SLASH "%s.socket", identname);
+
if(netname) {
if(!confbase)
xasprintf(&confbase, CONFDIR SLASH "tinc" SLASH "%s", netname);
void free_names(void) {
free(identname);
free(netname);
+ free(unixsocketname);
free(pidfilename);
free(logfilename);
free(confbase);
extern char *confbase;
extern char *netname;
extern char *identname;
+extern char *unixsocketname;
extern char *logfilename;
extern char *pidfilename;
extern char *program_name;
extern listen_socket_t listen_socket[MAXSOCKETS];
extern int listen_sockets;
+extern io_t unix_socket;
extern int keylifetime;
extern int udp_rcvbuf;
extern int udp_sndbuf;
extern void finish_connecting(struct connection_t *);
extern bool do_outgoing_connection(struct outgoing_t *);
extern void handle_new_meta_connection(void *, int);
+extern void handle_new_unix_connection(void *, int);
extern int setup_listen_socket(const sockaddr_t *);
extern int setup_vpn_in_socket(const sockaddr_t *);
extern bool send_sptps_data(void *handle, uint8_t type, const char *data, size_t len);
/* Open sockets */
+#ifndef HAVE_MINGW
+ int unix_fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if(unix_fd < 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not create UNIX socket: %s", sockstrerror(errno));
+ return false;
+ }
+
+ struct sockaddr_un sa;
+ sa.sun_family = AF_UNIX;
+ strncpy(sa.sun_path, unixsocketname, sizeof sa.sun_path);
+
+ if(connect(unix_fd, (struct sockaddr *)&sa, sizeof sa) >= 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "UNIX socket %s is still in use!", unixsocketname);
+ return false;
+ }
+
+ unlink(unixsocketname);
+
+ if(bind(unix_fd, (struct sockaddr *)&sa, sizeof sa) < 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not bind UNIX socket to %s: %s", unixsocketname, sockstrerror(errno));
+ return false;
+ }
+
+ if(listen(unix_fd, 3) < 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Could not listen on UNIX socket %s: %s", unixsocketname, sockstrerror(errno));
+ return false;
+ }
+
+ io_add(&unix_socket, handle_new_unix_connection, &unix_socket, unix_fd, IO_READ);
+#endif
+
if(!do_detach && getenv("LISTEN_FDS")) {
sockaddr_t sa;
socklen_t salen;
close(listen_socket[i].udp.fd);
}
+#ifndef HAVE_MINGW
+ io_del(&unix_socket);
+ close(unix_socket.fd);
+#endif
+
char *envp[5];
xasprintf(&envp[0], "NETNAME=%s", netname ? : "");
xasprintf(&envp[1], "DEVICE=%s", device ? : "");
#include "conf.h"
#include "connection.h"
+#include "control_common.h"
#include "list.h"
#include "logger.h"
#include "meta.h"
listen_socket_t listen_socket[MAXSOCKETS];
int listen_sockets;
+#ifndef HAVE_MINGW
+io_t unix_socket;
+#endif
list_t *outgoing_list = NULL;
/* Setup sockets */
send_id(c);
}
+#ifndef HAVE_MINGW
+/*
+ accept a new UNIX socket connection
+*/
+void handle_new_unix_connection(void *data, int flags) {
+ io_t *io = data;
+ connection_t *c;
+ sockaddr_t sa;
+ int fd;
+ socklen_t len = sizeof sa;
+
+ fd = accept(io->fd, &sa.sa, &len);
+
+ if(fd < 0) {
+ logger(DEBUG_ALWAYS, LOG_ERR, "Accepting a new connection failed: %s", sockstrerror(sockerrno));
+ return;
+ }
+
+ sockaddrunmap(&sa);
+
+ c = new_connection();
+ c->name = xstrdup("<control>");
+ c->address = sa;
+ c->hostname = xstrdup("localhost port unix");
+ c->socket = fd;
+ c->last_ping_time = time(NULL);
+
+ logger(DEBUG_CONNECTIONS, LOG_NOTICE, "Connection from %s", c->hostname);
+
+ io_add(&c->io, handle_meta_io, c, c->socket, IO_READ);
+
+ connection_add(c);
+
+ c->allow_request = ID;
+
+ send_id(c);
+}
+#endif
+
static void free_outgoing(outgoing_t *outgoing) {
timeout_del(&outgoing->ev);
}
#endif
+#ifndef HAVE_MINGW
+ struct sockaddr_un sa;
+ sa.sun_family = AF_UNIX;
+ strncpy(sa.sun_path, unixsocketname, sizeof sa.sun_path);
+
+ fd = socket(AF_UNIX, SOCK_STREAM, 0);
+ if(fd < 0) {
+ if(verbose)
+ fprintf(stderr, "Cannot create UNIX socket: %s\n", sockstrerror(sockerrno));
+ return false;
+ }
+
+ if(connect(fd, (struct sockaddr *)&sa, sizeof sa) < 0) {
+ if(verbose)
+ fprintf(stderr, "Cannot connect to UNIX socket %s: %s\n", unixsocketname, sockstrerror(sockerrno));
+ close(fd);
+ fd = -1;
+ return false;
+ }
+#else
struct addrinfo hints = {
.ai_family = AF_UNSPEC,
.ai_socktype = SOCK_STREAM,
}
freeaddrinfo(res);
+#endif
char data[4096];
int version;