diff --git a/contrib/c/sockettrap.c b/contrib/c/sockettrap.c new file mode 100644 index 000000000..e84c1c9ef --- /dev/null +++ b/contrib/c/sockettrap.c @@ -0,0 +1,103 @@ +/* vim: set expandtab ts=4 sw=4: */ +/* + * You may redistribute this program and/or modify it under the terms of + * the GNU General Public License as published by the Free Software Foundation, + * either version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <sys/types.h> +#include <sysexits.h> +#include <string.h> + +#include "util/Hex.h" +#include "memory/Allocator.h" +#include "memory/MallocAllocator.h" +#include "crypto/random/Random.h" +#include "io/FileReader.h" +#include "io/FileWriter.h" +#include "util/CString.h" +#include "util/Assert.h" +#include "util/log/Log.h" +#include "util/log/FileWriterLog.h" +#include "util/events/Time.h" +#include "util/events/EventBase.h" +#include "util/events/Pipe.h" +#include "util/events/Process.h" +#include "admin/angel/InterfaceWaiter.h" + +static void onCoreExit(int64_t exit_status, int term_signal) +{ + Assert_failure("Core exited with status [%d], signal [%d]\n", (int)exit_status, term_signal); +} + +/** + * Usage: + * pass an absolute path to cjdroute executable as an argument + * and this program will act as inetd boostrap, + * capturing data comming from STDIN and passing it as inital core config + * of cjdroute core and sending response on STDOUT. + **/ + +int main(int argc, char** argv) +{ + if (argc != 2) { + exit(EX_USAGE); + } + char* corePath = argv[1]; + + struct Except* eh = NULL; + + // Allow it to allocate 1MB + struct Allocator* allocator = MallocAllocator_new(1<<20); + struct Log* logger = NULL; // We don't want messages from the trap. + struct Random* rand = Random_new(allocator, logger, eh); + struct EventBase* eventBase = EventBase_new(allocator); + + struct Writer* stdoutWriter = FileWriter_new(stdout, allocator); + + struct Allocator* corePipeAlloc = Allocator_child(allocator); + char corePipeName[64] = "client-core-"; + Random_base32(rand, (uint8_t*)corePipeName+CString_strlen(corePipeName), 31); + Assert_ifParanoid(EventBase_eventCount(eventBase) == 0); + struct Pipe* corePipe = Pipe_named(corePipeName, eventBase, eh, corePipeAlloc); + corePipe->logger = logger; + Assert_ifParanoid(EventBase_eventCount(eventBase) == 2); + + struct Message* toCoreMsg = Message_new(0, 1024, allocator); + unsigned char buff[1024] = { 0 }; + int len; + do { + len = read(STDIN_FILENO, buff, 1024); + if (len <= 0 && errno != EAGAIN) { + fprintf(stderr, "Read returned: %d with errno %s.\n", len, strerror(errno)); + exit(EX_NOINPUT); + } + // read will return -1 and set errno if there is nonblocking pipe. + } while (len == -1 && errno == EAGAIN); + + Message_push(toCoreMsg, buff, len, eh); + + char* args[] = { "core", corePipeName, NULL }; + + Process_spawn(corePath, args, eventBase, allocator, onCoreExit); + + + Iface_CALL(corePipe->iface.send, toCoreMsg, &corePipe->iface); + + struct Message* fromCoreMsg = + InterfaceWaiter_waitForData(&corePipe->iface, eventBase, allocator, eh); + Writer_write(stdoutWriter, fromCoreMsg->bytes, fromCoreMsg->length); + + return 0; +} diff --git a/contrib/systemd/README.md b/contrib/systemd/README.md new file mode 100644 index 000000000..d168109fe --- /dev/null +++ b/contrib/systemd/README.md @@ -0,0 +1,6 @@ +## How to install + +```bash +mv contrib/systemd/cjdns* /usr/lib/systemd/systemd/ +mv ./sockettrap /usr/lib/systemd/scripts/cjdns-trap +``` diff --git a/contrib/systemd/cjdns.socket b/contrib/systemd/cjdns.socket new file mode 100644 index 000000000..f52b05583 --- /dev/null +++ b/contrib/systemd/cjdns.socket @@ -0,0 +1,11 @@ +[Unit] +Description=Cjdns activation socket. + +[Socket] +ListenStream=/run/cjdns/cjdns.socket +Accept=true +SocketMode=0600 + +[Install] +WantedBy=sockets.target + diff --git a/contrib/systemd/cjdns@.service b/contrib/systemd/cjdns@.service new file mode 100644 index 000000000..7873a1ca9 --- /dev/null +++ b/contrib/systemd/cjdns@.service @@ -0,0 +1,16 @@ +[Unit] +Description=cjdns-multinstant: routing engine designed for security, scalability, speed and ease of use +Wants=network.target +After=network.target +Requires=cjdns.socket + +[Service] +ProtectHome=true +ProtectSystem=true +SyslogIdentifier=cjdroute + +Type=forking +ExecStart=/usr/lib/systemd/scripts/cjdns-trap /usr/bin/cjdroute +StandardInput=socket +StandardOutput=socket +StandardError=journal diff --git a/node_build/make.js b/node_build/make.js index 76eba557b..fbaa4d875 100644 --- a/node_build/make.js +++ b/node_build/make.js @@ -409,6 +409,10 @@ Builder.configure({ builder.buildExecutable('contrib/c/privatetopublic.c'); builder.buildExecutable('contrib/c/sybilsim.c'); builder.buildExecutable('contrib/c/makekeys.c'); + if (builder.config.systemName !== 'win32') { + // Everything else is UNIX based. + builder.buildExecutable('contrib/c/sockettrap.c'); + } builder.buildExecutable('crypto/random/randombytes.c');