diff options
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/local.mk | 1 | ||||
-rw-r--r-- | gnu/services/networking.scm | 89 | ||||
-rw-r--r-- | gnu/tests/networking.scm | 149 |
3 files changed, 239 insertions, 0 deletions
diff --git a/gnu/local.mk b/gnu/local.mk index f589cd9468..0bb2276a2a 100644 --- a/gnu/local.mk +++ b/gnu/local.mk @@ -464,6 +464,7 @@ GNU_SYSTEM_MODULES = \ %D%/tests/install.scm \ %D%/tests/mail.scm \ %D%/tests/messaging.scm \ + %D%/tests/networking.scm \ %D%/tests/ssh.scm \ %D%/tests/web.scm diff --git a/gnu/services/networking.scm b/gnu/services/networking.scm index 9b8e5b36b1..85fc0b843a 100644 --- a/gnu/services/networking.scm +++ b/gnu/services/networking.scm @@ -4,6 +4,7 @@ ;;; Copyright © 2016 Efraim Flashner <efraim@flashner.co.il> ;;; Copyright © 2016 John Darrington <jmd@gnu.org> ;;; Copyright © 2017 Clément Lassieur <clement@lassieur.org> +;;; Copyright © 2017 Thomas Danckaert <post@thomasdanckaert.be> ;;; ;;; This file is part of GNU Guix. ;;; @@ -61,6 +62,10 @@ ntp-service ntp-service-type + inetd-configuration + inetd-entry + inetd-service-type + tor-configuration tor-configuration? tor-hidden-service @@ -432,6 +437,90 @@ make an initial adjustment of more than 1,000 seconds." ;;; +;;; Inetd. +;;; + +(define-record-type* <inetd-configuration> inetd-configuration + make-inetd-configuration + inetd-configuration? + (program inetd-configuration-program ;file-like + (default (file-append inetutils "/libexec/inetd"))) + (entries inetd-configuration-entries ;list of <inetd-entry> + (default '()))) + +(define-record-type* <inetd-entry> inetd-entry make-inetd-entry + inetd-entry? + (node inetd-entry-node ;string or #f + (default #f)) + (name inetd-entry-name) ;string, from /etc/services + + (socket-type inetd-entry-socket-type) ;stream | dgram | raw | + ;rdm | seqpacket + (protocol inetd-entry-protocol) ;string, from /etc/protocols + + (wait? inetd-entry-wait? ;Boolean + (default #t)) + (user inetd-entry-user) ;string + + (program inetd-entry-program ;string or file-like object + (default "internal")) + (arguments inetd-entry-arguments ;list of strings or file-like objects + (default '()))) + +(define (inetd-config-file entries) + (apply mixed-text-file "inetd.conf" + (map + (lambda (entry) + (let* ((node (inetd-entry-node entry)) + (name (inetd-entry-name entry)) + (socket + (if node (string-append node ":" name) name)) + (type + (match (inetd-entry-socket-type entry) + ((or 'stream 'dgram 'raw 'rdm 'seqpacket) + (symbol->string (inetd-entry-socket-type entry))))) + (protocol (inetd-entry-protocol entry)) + (wait (if (inetd-entry-wait? entry) "wait" "nowait")) + (user (inetd-entry-user entry)) + (program (inetd-entry-program entry)) + (args (inetd-entry-arguments entry))) + #~(string-append + (string-join + (list #$@(list socket type protocol wait user program) #$@args) + " ") "\n"))) + entries))) + +(define inetd-shepherd-service + (match-lambda + (($ <inetd-configuration> program ()) '()) ; empty list of entries -> do nothing + (($ <inetd-configuration> program entries) + (list + (shepherd-service + (documentation "Run inetd.") + (provision '(inetd)) + (requirement '(user-processes networking syslogd)) + (start #~(make-forkexec-constructor + (list #$program #$(inetd-config-file entries)) + #:pid-file "/var/run/inetd.pid")) + (stop #~(make-kill-destructor))))))) + +(define-public inetd-service-type + (service-type + (name 'inetd) + (extensions + (list (service-extension shepherd-root-service-type + inetd-shepherd-service))) + + ;; The service can be extended with additional lists of entries. + (compose concatenate) + (extend (lambda (config entries) + (inetd-configuration + (inherit config) + (entries (append (inetd-configuration-entries config) + entries))))))) + + +;;; ;;; Tor. ;;; diff --git a/gnu/tests/networking.scm b/gnu/tests/networking.scm new file mode 100644 index 0000000000..53c80a4ac1 --- /dev/null +++ b/gnu/tests/networking.scm @@ -0,0 +1,149 @@ +;;; GNU Guix --- Functional package management for GNU +;;; Copyright © 2017 Thomas Danckaert <post@thomasdanckaert.be> +;;; +;;; This file is part of GNU Guix. +;;; +;;; GNU Guix is free software; you can redistribute it 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. +;;; +;;; GNU Guix 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 GNU Guix. If not, see <http://www.gnu.org/licenses/>. + +(define-module (gnu tests networking) + #:use-module (gnu tests) + #:use-module (gnu system) + #:use-module (gnu system grub) + #:use-module (gnu system file-systems) + #:use-module (gnu system shadow) + #:use-module (gnu system vm) + #:use-module (gnu services) + #:use-module (gnu services base) + #:use-module (gnu services networking) + #:use-module (guix gexp) + #:use-module (guix store) + #:use-module (guix monads) + #:use-module (gnu packages bash) + #:export (%test-inetd)) + +(define %inetd-os + ;; Operating system with 2 inetd services. + (operating-system + (host-name "komputilo") + (timezone "Europe/Brussels") + (locale "en_US.utf8") + + (bootloader (grub-configuration (device "/dev/sdX"))) + (file-systems %base-file-systems) + (firmware '()) + (users %base-user-accounts) + (services (cons* (dhcp-client-service) + (service inetd-service-type + (inetd-configuration + (entries (list + (inetd-entry + (name "echo") + (socket-type 'stream) + (protocol "tcp") + (wait? #f) + (user "root")) + (inetd-entry + (name "dict") + (socket-type 'stream) + (protocol "tcp") + (wait? #f) + (user "root") + (program (file-append bash + "/bin/bash")) + (arguments + (list "bash" (plain-file "my-dict.sh" "\ +while read line +do + if [[ $line =~ ^DEFINE\\ (.*)$ ]] + then + case ${BASH_REMATCH[1]} in + Guix) + echo GNU Guix is a package management tool for the GNU system. + ;; + G-expression) + echo Like an S-expression but with a G. + ;; + *) + echo NO DEFINITION FOUND + ;; + esac + else + echo ERROR + fi +done" )))))))) + %base-services)))) + +(define* (run-inetd-test) + "Run tests in %INETD-OS, where the inetd service provides an echo service on +port 7, and a dict service on port 2628." + (mlet* %store-monad ((os -> (marionette-operating-system %inetd-os)) + (command (system-qemu-image/shared-store-script + os #:graphic? #f))) + (define test + (with-imported-modules '((gnu build marionette)) + #~(begin + (use-modules (ice-9 rdelim) + (srfi srfi-64) + (gnu build marionette)) + (define marionette + ;; Forward guest ports 7 and 2628 to host ports 8007 and 8628. + (make-marionette (list #$command "-net" + (string-append + "user" + ",hostfwd=tcp::8007-:7" + ",hostfwd=tcp::8628-:2628")))) + + (mkdir #$output) + (chdir #$output) + + (test-begin "inetd") + + ;; Make sure the PID file is created. + (test-assert "PID file" + (marionette-eval + '(file-exists? "/var/run/inetd.pid") + marionette)) + + ;; Test the echo service. + (test-equal "echo response" + "Hello, Guix!" + (let ((echo (socket PF_INET SOCK_STREAM 0)) + (addr (make-socket-address AF_INET INADDR_LOOPBACK 8007))) + (connect echo addr) + (display "Hello, Guix!\n" echo) + (let ((response (read-line echo))) + (close echo) + response))) + + ;; Test the dict service + (test-equal "dict response" + "GNU Guix is a package management tool for the GNU system." + (let ((dict (socket PF_INET SOCK_STREAM 0)) + (addr (make-socket-address AF_INET INADDR_LOOPBACK 8628))) + (connect dict addr) + (display "DEFINE Guix\n" dict) + (let ((response (read-line dict))) + (close dict) + response))) + + (test-end) + (exit (= (test-runner-fail-count (test-runner-current)) 0))))) + + (gexp->derivation "inetd-test" test))) + +(define %test-inetd + (system-test + (name "inetd") + (description "Connect to a host with an INETD server.") + (value (run-inetd-test)))) |