diff options
| author | Artyom V. Poptsov <poptsov.artyom@gmail.com> | 2015-07-31 01:43:27 +0300 |
|---|---|---|
| committer | Artyom V. Poptsov <poptsov.artyom@gmail.com> | 2015-07-31 01:43:27 +0300 |
| commit | 62b88d0cbbb80ce616ed4de4c6d9302f7bb0b13a (patch) | |
| tree | c0417b0dfb6566b217fd145679881bc38e786e06 | |
| parent | modules/ssh/Makefile.am (guilec_env): Fix guile load path (diff) | |
| download | guile-ssh-62b88d0cbbb80ce616ed4de4c6d9302f7bb0b13a.tar.gz | |
examples/rpc/{client,server}.scm.in: Add to the repository
* examples/rpc/client.scm.in, examples/rpc/server.scm.in: Add to the
repository.
* doc/api-channels.texi: Mention a path to the full RPC client example in the
description of 'call-with-ssh-forward'.
* examples/Makefile.am: Add 'rpc/client.scm.in', rpc/server.scm.in.
* examples/.gitignore: Ignore 'rpc/client.scm', 'rpc/server.scm'.
* examples/README: Update.
| -rw-r--r-- | doc/api-channels.texi | 3 | ||||
| -rw-r--r-- | examples/.gitignore | 2 | ||||
| -rw-r--r-- | examples/Makefile.am | 9 | ||||
| -rw-r--r-- | examples/README | 3 | ||||
| -rw-r--r-- | examples/rpc/client.scm.in | 105 | ||||
| -rw-r--r-- | examples/rpc/server.scm.in | 71 |
6 files changed, 191 insertions, 2 deletions
diff --git a/doc/api-channels.texi b/doc/api-channels.texi index 7e5a9ea..537e6b8 100644 --- a/doc/api-channels.texi +++ b/doc/api-channels.texi @@ -382,6 +382,9 @@ you can implement an RPC call using @code{call-with-ssh-forward}: (lambda (socket) (RPC-PROGRAM-proc some-data #x123 socket)))) @end lisp + +The full example of an RPC client that uses a SSH tunnel is in +@file{$prefix/share/guile-ssh/examples/rpc} directory. @end deffn @subsection Example diff --git a/examples/.gitignore b/examples/.gitignore index 9dccecc..d6d9e9b 100644 --- a/examples/.gitignore +++ b/examples/.gitignore @@ -6,4 +6,6 @@ sssh.scm ssshd.scm echo/client.scm echo/server.scm +rpc/client.scm +rpc/server.scm Makefile.in diff --git a/examples/Makefile.am b/examples/Makefile.am index ed49ffa..0c79edc 100644 --- a/examples/Makefile.am +++ b/examples/Makefile.am @@ -21,12 +21,16 @@ EXTRA_DIST = \ ssshd.scm.in \ echo/server.scm.in \ echo/client.scm.in \ - rrepl.scm.in + rrepl.scm.in \ + rpc/client.scm.in \ + rpc/server.scm.in examplesdir = $(pkgdatadir)/examples examples_echodir = $(pkgdatadir)/examples/echo +examples_rpcdir = $(pkgdatadir)/examples/rpc dist_examples_DATA = README sssh.scm ssshd.scm rrepl.scm dist_examples_echo_DATA = echo/server.scm echo/client.scm +dist_examples_rpc_DATA = rpc/client.scm rpc/server.scm substitute = sed -e 's,[@]GUILE[@],$(GUILE),g' @@ -40,4 +44,5 @@ SUFFIXES = .in CLEANFILES = \ sssh.scm ssshd.scm \ echo/server.scm echo/client.scm \ - rrepl.scm + rrepl.scm \ + rpc/server.scm rpc/client.scm diff --git a/examples/README b/examples/README index 49e3242..6735ce3 100644 --- a/examples/README +++ b/examples/README @@ -40,3 +40,6 @@ Please find sources in =echo/= directory: * RREPL A demo program that allows to connect to a remote REPL (RREPL) server. Pass =--help= (or =-h=) flag to the program to get usage information. +* RPC over SSH + A demo RPC client program that uses an SSH tunnel to make an RPC call over a + secure connection. See =rpc/= directory. diff --git a/examples/rpc/client.scm.in b/examples/rpc/client.scm.in new file mode 100644 index 0000000..d48c3a0 --- /dev/null +++ b/examples/rpc/client.scm.in @@ -0,0 +1,105 @@ +#!@GUILE@ \ +-e main +!# + +;;; client.scm -- An example of an RPC call over a SSH tunnel. + +;; Copyright (C) 2015 Artyom V. Poptsov <poptsov.artyom@gmail.com> +;; +;; This program 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. +;; +;; 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/>. + + +;;; Commentary: + +;; A demo program that makes an RPC call over a SSH tunnel. For simplicity +;; the program uses ssh-agent for authentication. +;; +;; The basic code for the RPC call is taken from Guile-RPC documentation. + + +;;; Code: + +(use-modules (ice-9 getopt-long) + ;; RPC + (rpc rpc) + (rpc xdr) + (rpc xdr types) + ;; Guile-SSH + (ssh session) + (ssh auth) + (ssh tunnel)) + +(define result-type + (make-xdr-struct-type (list xdr-integer ;; `integer_part' + xdr-unsigned-integer))) ;; `decimal_part' + +(define invoke-split-number + (make-synchronous-rpc-call 80000 0 ;; program and version + 1 ;; procedure number + xdr-double ;; argument type + result-type)) + +(define (print-help-and-exit) + "Print information about program usage." + (display "\ +Usage: rrepl.scm [options] <host> + +Connect to a remote REPL (RREPL) using an ssh-agent for authentication. + +Options: + --user, -u <user> User name. + --port, -p <port> SSH port number (default: 22) + --help, -h Print this message and exit. +") + (exit)) + +(define (main args) + "Entry point of the program." + (let* ((options-spec '((user (single-char #\u) (value #t)) + (port (single-char #\p) (value #t)) + (help (single-char #\h) (value #f)))) + (options (getopt-long args options-spec)) + (user (option-ref options 'user (getenv "USER"))) + (port (option-ref options 'port "22")) + (help-needed? (option-ref options 'help #f)) + (args (option-ref options '() #f))) + + (and (or help-needed? + (not args) + (null? args)) + (print-help-and-exit)) + + ;; Make a new SSH session, connect it and authenticate the user. + (let* ((host (car args)) + (session (make-session #:user user + #:host host + #:port (string->number port) + #:log-verbosity 'nolog))) + (connect! session) + (userauth-agent! session) + ;; Make a new SSH tunnel. + (let ((tunnel (make-tunnel session + #:port 12345 + ;; Guile-RPC server listens on localhost. + #:host "127.0.0.1" ; + ;; Guile-RPC server port. + #:host-port 6666))) + ;; Make an RPC call using the SSH tunnel. + (call-with-ssh-forward tunnel + (lambda (socket) + (display (invoke-split-number 3.14 #x7777 socket)) + (newline))))))) + +;;; client.scm ends here. diff --git a/examples/rpc/server.scm.in b/examples/rpc/server.scm.in new file mode 100644 index 0000000..6652300 --- /dev/null +++ b/examples/rpc/server.scm.in @@ -0,0 +1,71 @@ +#!@GUILE@ \ +-e main +!# + +;;; server.scm -- An simple RPC server. + +;; Copyright (C) 2015 Artyom V. Poptsov <poptsov.artyom@gmail.com> +;; +;; This program 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. +;; +;; 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/>. + + +;;; Commentary: + +;; A simple RPC server. +;; +;; The code for the server is taken from Guile-RPC documentation. + + +;;; Code: + + +;; Taken from Guile-RPC examples. + +(use-modules (rpc rpc server) + (rpc xdr) + (rpc xdr types)) + +(define (split-number-handler number) + ;; Handle a `split-number' request. + (let* ((int (floor number)) + (dec (floor (* 1000 (- number int))))) + (list (inexact->exact int) + (inexact->exact dec)))) + +(define result-type + (make-xdr-struct-type (list xdr-integer ;; `integer_part' + xdr-unsigned-integer))) ;; `decimal_part' + +(define my-rpc-program + ;; Define our RPC program. + (let* ((proc (make-rpc-procedure 1 xdr-double result-type + split-number-handler)) + (version (make-rpc-program-version 0 (list proc)))) + (make-rpc-program 80000 (list version)))) + +(define (main args) + "Entry point of the program." + (let ((server-socket (socket PF_INET SOCK_STREAM 0))) + (bind server-socket AF_INET INADDR_LOOPBACK 6666) + (listen server-socket 1024) + + ;; Go ahead and serve requests. + (run-stream-rpc-server (list (cons server-socket my-rpc-program)) + 1000000 ;; a one-second timeout + #f ;; we don't care about closed connections + (lambda () ;; our idle thunk + (format #t "one second passed~%"))))) + +;;; server.scm ends here. |
