[Libguestfs] [PATCH nbdkit 3/4] server: Add nbdkit_peer_name() to return the client address.

Richard W.M. Jones rjones at redhat.com
Sun Sep 15 14:55:44 UTC 2019


Works essentially just like calling getpeername(2), because that's how
it is implemented.
---
 TODO                    |  6 ++++++
 docs/nbdkit-plugin.pod  | 23 +++++++++++++++++++++++
 include/nbdkit-common.h |  2 ++
 server/nbdkit.syms      |  1 +
 server/public.c         | 21 +++++++++++++++++++++
 5 files changed, 53 insertions(+)

diff --git a/TODO b/TODO
index 04def3c..d2cf0ae 100644
--- a/TODO
+++ b/TODO
@@ -77,6 +77,12 @@ General ideas for improvements
   name(s) that a plugin might want to support.  Probably we should
   deprecate the -e option entirely since it does nothing useful.
 
+* Add plugin "connect" method.  This would be called on a connection
+  before handshaking or TLS negotiation, and could be used (with
+  nbdkit_peer_name) to accept or reject connections based on IP
+  address, rather like a poor man's TCP wrappers.  See also commit
+  c05686f9577f.
+
 Suggestions for plugins
 -----------------------
 
diff --git a/docs/nbdkit-plugin.pod b/docs/nbdkit-plugin.pod
index 39fa643..70d2d64 100644
--- a/docs/nbdkit-plugin.pod
+++ b/docs/nbdkit-plugin.pod
@@ -391,6 +391,29 @@ On error, C<nbdkit_error> is called and the call returns C<NULL>.
 
 See also L<nbdkit-reflection-plugin(1)>.
 
+=head1 PEER NAME
+
+It is possible to get the address of the client when you are running
+in any connected callback.
+
+=head2 C<nbdkit_peer_name>
+
+ int nbdkit_peer_name (struct sockaddr *addr, socklen_t *addrlen);
+
+Return the peer (client) address, if available.  The C<addr> and
+C<addrlen> parameters behave like L<getpeername(2)>.  In particular
+you must initialize C<addrlen> with the size of the buffer pointed to
+by C<addr>, and if C<addr> is not large enough then the address will
+be truncated.
+
+In some cases this is not available or the address returned will be
+meaningless (eg. if there is a proxy between the client and nbdkit).
+This call uses thread-local magic so no parameter is required to
+specify the current connection.
+
+On success this returns C<0>.  On error, C<nbdkit_error> is called and
+this call returns C<-1>.
+
 =head1 CALLBACKS
 
 =head2 C<.name>
diff --git a/include/nbdkit-common.h b/include/nbdkit-common.h
index acf0abd..aac63fb 100644
--- a/include/nbdkit-common.h
+++ b/include/nbdkit-common.h
@@ -40,6 +40,7 @@
 #include <stdarg.h>
 #include <stdint.h>
 #include <errno.h>
+#include <sys/socket.h>
 
 #include <nbdkit-version.h>
 
@@ -87,6 +88,7 @@ extern int nbdkit_read_password (const char *value, char **password);
 extern char *nbdkit_realpath (const char *path);
 extern int nbdkit_nanosleep (unsigned sec, unsigned nsec);
 extern const char *nbdkit_export_name (void);
+extern int nbdkit_peer_name (struct sockaddr *addr, socklen_t *addrlen);
 
 struct nbdkit_extents;
 extern int nbdkit_add_extent (struct nbdkit_extents *,
diff --git a/server/nbdkit.syms b/server/nbdkit.syms
index 1fb1315..d792a5f 100644
--- a/server/nbdkit.syms
+++ b/server/nbdkit.syms
@@ -50,6 +50,7 @@
     nbdkit_nanosleep;
     nbdkit_parse_bool;
     nbdkit_parse_size;
+    nbdkit_peer_name;
     nbdkit_read_password;
     nbdkit_realpath;
     nbdkit_set_error;
diff --git a/server/public.c b/server/public.c
index 96ab353..c8b06a6 100644
--- a/server/public.c
+++ b/server/public.c
@@ -49,6 +49,7 @@
 #include <errno.h>
 #include <poll.h>
 #include <signal.h>
+#include <sys/socket.h>
 
 #include "get-current-dir-name.h"
 
@@ -392,3 +393,23 @@ nbdkit_export_name (void)
 
   return conn->exportname;
 }
+
+int
+nbdkit_peer_name (struct sockaddr *addr, socklen_t *addrlen)
+{
+  struct connection *conn = threadlocal_get_conn ();
+  int s;
+
+  if (!conn) {
+    nbdkit_error ("no connection in this thread");
+    return -1;
+  }
+
+  s = conn->sockin;
+  if (s == -1) {
+    nbdkit_error ("socket not open");
+    return -1;
+  }
+
+  return getpeername (s, addr, addrlen);
+}
-- 
2.23.0




More information about the Libguestfs mailing list